HDU4348To the moon主席树,区间修改
题意:
一个长度为n的数组,4种操作 :
(1)C l r d:区间[l,r]中的数都加1,同时当前的时间戳加1 。
(2)Q l r:查询当前时间戳区间[l,r]中所有数的和 。
(3)H l r t:查询时间戳t区间[l,r]的和 。
(4)B t:将当前时间戳置为t 。
(第一次修改t为1;
思路:被https://www.cnblogs.com/hsd-/p/6506175.html思路坑了一下午,好吧就是自己没懂
然后看到vjudge上的一个思路;感觉这个思路更清晰;
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> using namespace std; #define pb push_back typedef long long ll; const int maxn = 100009; struct node { int l,r; ll sum,lazy; }T[maxn*40]; int root[maxn],cur,tot; ll a[maxn]; void build(int l,int r,int &pos) { pos = tot++; T[pos].sum = T[pos].lazy = 0; // T[pos].l = l,T[pos].r = r; if(l==r) { T[pos].sum = a[l]; return; } int mid = (l+r)>>1; build(l,mid,T[pos].l); build(mid+1,r,T[pos].r); T[pos].sum = T[T[pos].l].sum + T[T[pos].r].sum; } void update(int L,int R, int &x, int y , int l, int r, int d)//这里的x和上面的pos类似 { x = tot++; T[x] = T[y]; if(l>=L && r<=R) { T[x].sum += 1ll*(r - l + 1) * d; //这里用目标区间的L,R;因为目标区间每个值都要加上 T[x].lazy += d; return; } int mid = (l+r)>>1; if(L <= mid) update(L, R, T[x].l, T[y].l, l, mid, d); if(R > mid) update(L, R, T[x].r, T[y].r, mid+1,r, d); T[x].sum = T[T[x].l].sum + T[T[x].r].sum + 1ll*(r-l+1) * T[x].lazy; } ll query(int L,int R,int x,int l,int r) { if(L<=l && R>=r) { return T[x].sum; } ll ans = 1ll*T[x].lazy*(min(R,r)-max(L,l) + 1); int mid = (l+r)>>1; if(R > mid) ans += query(L,R,T[x].r, mid+1, r); if(L<=mid) ans += query(L,R,T[x].l, l,mid); return ans; } int main() { int n,m; int flag = 0; while(~scanf("%d%d", &n, &m)) { if(flag)puts(""); flag = 1; tot = 0,cur = 0; for(int i=1; i<=n; i++) { scanf("%lld", &a[i]); } // root[0] = tot++; build(1,n,root[0]); while(m--) { char op[20]; scanf("%s" , op); if(op[0]=='Q') { int l,r; scanf("%d%d",&l,&r); printf("%lld\n",query(l,r,root[cur],1,n)); } else if(op[0]=='C') { int l,r; ll d; scanf("%d%d%lld", &l, &r, &d); cur++; update(l,r,root[cur],root[cur-1], 1, n, d); } else if(op[0]=='H') { int l,r,t; scanf("%d%d%d",&l,&r,&t); printf("%lld\n",query(l,r,root[t],1,n)); } else if(op[0]=='B') { scanf("%d",&cur); } } } return 0; }
skr