2 条题解

  • 2
    @ 2023-5-31 19:10:40

    image

    #include <bits/stdc++.h>
    using namespace std;
    #define mid ((l + r) >> 1)
    const int maxn = 5e5 + 10;
    int n, m;
    struct tree{
    	int Amx, Bmn, lx, rx, mx;
    }a[maxn << 3];
    struct node {
    	int a, b;
    }b[maxn];
    tree update(tree A, tree B) {
    	tree T;
    	T.Amx = max(A.Amx, B.Amx);
    	T.Bmn = min(A.Bmn, B.Bmn);
    	T.lx = A.Amx - B.Bmn; //需要满足A的位置在B前面
    	T.rx = B.Amx - A.Bmn; //需要满足B的位置在A前面
    	T.lx = max(T.lx, max(A.lx, B.lx));
    	T.rx = max(T.rx, max(A.rx, B.rx));
    	T.mx = max(A.lx + B.Amx, B.rx + A.Amx); //对应以上说的 3 4 操作
    	T.mx = max(T.mx, max(A.mx, B.mx)); //1 2 
    	return T;
    }
    void build(int p, int l, int r) {
    	if(l == r) {
    		a[p].Amx = b[l].a, a[p].Bmn = b[l].b;
    		a[p].lx = a[p].rx = a[p].mx = -0x3f3f3f3f; //不保证A都大于B 所以要初始化
    		return;
    	}
    	build(p<<1,l,mid), build(p<<1|1,mid+1,r);
    	a[p] = update(a[p<<1], a[p<<1|1]);
    }
    void change(int p, int l, int r, int pos, int k, int op) { //单点修改
    	if(l == r) {
    		if(op == 1) a[p].Amx = k;
    		if(op == 2) a[p].Bmn = k;
    		return;
    	}
    	if(pos <= mid) change(p<<1,l,mid,pos,k,op);
    	if(pos >  mid) change(p<<1|1,mid+1,r,pos,k,op);
    	a[p] = update(a[p<<1], a[p<<1|1]);
    }
    tree query(int p, int l, int r, int L, int R) { //区间查询
    	if(L <= l && r <= R) return a[p];
    	if(L >  mid) return query(p<<1|1,mid+1,r, L, R); //全在右区间
    	if(R <= mid) return query(p<<1,l,mid, L, R); //全在左区间
    	return update(query(p<<1,l,mid, L, R), query(p<<1|1,mid+1,r, L, R)); 
    	//两个区间合并与change build函数中一样
    }
    int main() {
    //	freopen("in.txt","r",stdin);
    	scanf("%d%d", &n, &m);
    	for(int i = 1;i <= n;i++) scanf("%d", &b[i].a);
    	for(int i = 1;i <= n;i++) scanf("%d", &b[i].b);
    	build(1, 1, n);
    	for(int i = 1;i <= m;i++) {
    		int op, x, y;
    		scanf("%d%d%d", &op, &x, &y);
    		if(op == 1)	change(1, 1, n, x, y, 1);
    		if(op == 2) change(1, 1, n, x, y, 2);
    		if(op == 3) printf("%d\n", query(1, 1, n, x, y).mx);
    	}
    	return 0;
    }
    
    • 0
      @ 2023-9-6 11:12:48

      题目难度属于半裸题,难点在于下面题解看不懂 下面我浅浅说一下 其余不多说,易错点是查找的时候需要注意等号要不然会爆 言归正传 只说一下push_up(强烈建议先做前一题) 给定五个维护量 第一个max 含义Ai +Aj - Bk 最大值 Amax 含义在l-r区间内A最大值 Bmin 含义在l-r区间内B最小值 ab 含义Ai - Bk 最大值 bc 含义Aj - Bk 最大值 具体维护看代码,比较好理解 暑假的救赎day4 启动!

      #include <bits/stdc++.h>
      using namespace std;
      struct Node{
      	int Amax,Bmin,ab,bc,max;
      };
      Node a[4000005];
      int n,m,c1[2000005],c2[2000005];
      
      Node push_up(Node x,Node y)
      {
      	Node p;
      	p.Amax = max(x.Amax,y.Amax);
      	p.Bmin = min(x.Bmin,y.Bmin);
      	p.max = max(x.Amax + y.bc , x.ab + y.Amax);
      	p.max = max(max(x.max,y.max),p.max);
      	p.ab = max(max(x.ab,y.ab),x.Amax - y.Bmin);
      	p.bc = max(max(x.bc,y.bc),y.Amax - x.Bmin);
      	return p;
      }
      void out(Node P)
      {
      	cout << P.max << " " << P.Amax << " " << P.Bmin << " " << P.ab  << " " << P.bc << endl; 
      }
      void build(int k,int l,int r)
      {
      	if(l == r)
      	{
      		a[k].Amax = c1[l];
      		a[k].Bmin = c2[l];
      		a[k].max = a[k].ab = a[k].bc = -0x3f3f3f3f;
      		return;
      	}
      	int mid = (l+r) / 2;
      	build(2*k,l,mid);
      	build(2*k+1,mid+1,r);
      	a[k] = push_up(a[k*2] ,a[k*2+1]);
      }
      void change(int k,int l,int r , int s,int t,int op)
      {
      	if(l == r)
      	{
      		if(op == 1) 
      		    a[k].Amax = t;
      		if(op == 2)
      		    a[k].Bmin = t;
      		return;
      	}
      	int mid = (l + r)/2;
      	if(s <= mid) change(k*2,l,mid,s,t,op);
      	else change(k * 2 + 1,mid+1,r,s,t,op);
      	a[k] = push_up(a[k*2],a[k*2+1]); 
      }
      Node sum(int k,int l,int r,int s,int t)
      {
      	if(s <= l && r <= t)
      	{
      		return a[k];
      	}
      	int mid = (l+r) / 2;
      	if(s <= mid && mid < t)
      		return push_up(sum(k*2,l,mid,s,t),sum(k*2+1,mid+1,r,s,t));
      	else if(s <= mid)
      		return sum(k*2,l,mid,s,t);
      	else
      	    return sum(k*2+1,mid+1,r,s,t);
      }
      int main()
      {
      	ios::sync_with_stdio(false);
      	cin.tie(0),cout.tie(0);
      	cin >> n >> m;
      	for(int i=1; i <= n; i++)
      		cin >> c1[i];
      	for(int i=1; i <= n ;i++)
      	    cin >> c2[i];
      	build(1,1,n);
      	for(int i=1; i <= m ;i++)
      	{
      		int op, x,y;
      		cin >> op >> x >> y;
      		if(op == 1)
      			change(1,1,n,x,y,op);
      		if(op==2)
      		    change(1,1,n,x,y,op);
      		if(op == 3)
      		{
      			Node ans = sum(1,1,n,x,y);
      			cout << ans.max << '\n';
      		}
      	}
      	return 0;
      } 
      
      • 1

      「Wdsr-2.7」文文的摄影布置

      信息

      ID
      121
      时间
      2000ms
      内存
      256MiB
      难度
      3
      标签
      (无)
      递交数
      77
      已通过
      39
      上传者