2 条题解
-
2
#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
题目难度属于半裸题,难点在于下面题解看不懂 下面我浅浅说一下 其余不多说,易错点是查找的时候需要注意等号要不然会爆 言归正传 只说一下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
信息
- ID
- 121
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- (无)
- 递交数
- 77
- 已通过
- 39
- 上传者