线段树(单点更新)
/* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 500002; const ll maxm = 1e7; const ll base = 2333; const int INF = 1<<30; const db eps = 1e-8; const ll mod = 1e9+13; struct nodee{ int left, right, mid, num; }node[maxn]; int ca=1; void build(int left, int right, int n) { node[n].left=left; node[n].right=right; node[n].mid=(left+right)/2; node[n].num=0; if (left+1==right) return; build(left, (left+right)/2, 2*n); build((left+right)/2, right, 2*n+1); } void updata(int pos, int value, int n) { node[n].num+=value; if (node[n].left+1==node[n].right) return; if (pos<node[n].mid) updata(pos, value, 2*n); else updata(pos, value, 2*n+1); } int query(int left, int right, int n) { if (node[n].left==left && node[n].right==right) { return node[n].num; } if (left<node[n].mid) { if(right <= node[n].mid ){ return query(left,right,2*n); } else{ return query(left,node[n].mid,2*n) + query(node[n].mid,right,2*n + 1); } } else return query(left,right,2*n+1); } void solve() { int n; scanf("%d", &n); build(1, n+1, 1); for (int i=1; i<=n; i++) { int x; scanf("%d", &x); updata(i, x, 1); } char c[10]; printf("Case %d:\n", ca++); while(1) { scanf("%s", c); if (strcmp(c, "End")==0) break; int x, y; scanf("%d%d", &x, &y); if (strcmp(c, "Query")==0) { int ans=query(x, y+1, 1); printf("%d\n", ans); } else if(strcmp(c,"Add") == 0){ updata(x, y, 1); } else if(strcmp(c,"Sub") == 0){ updata(x, -y, 1); } } } int main() { int t = 1; // freopen("in.txt","r",stdin); // freopen("gcd.out","w",stdout); scanf("%d", &t); while(t--) solve(); return 0; }
dfs序+线段树
将dfs序作为建树的标准
/* gyt Live up to every day */ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; #define LL(x) (x<<1) #define RR(x) (x<<1|1) const int maxn = 100000+5; const ll maxm = 1e7; const ll base = 2333; const ll inf = 1e17; const db eps = 1e-8; const ll mod = 1e9+13; int a[maxn], n, m, cnt, head[maxn]; int in[maxn], out[maxn], xx, idx[maxn]; ll dis[maxn]; int ca=1; struct Edge{ int v, next; }e[maxn*2]; struct TREE{ int l, r; ll val, maxx, lazy; void fun(ll tmp) { lazy+=tmp; val+=(r-l+1)*tmp; maxx+=tmp; } }tree[maxn*4]; void init() { xx=cnt=0; memset(head, -1, sizeof(head)); } void add(int u, int v) { e[cnt].v=v, e[cnt].next=head[u]; head[u]=cnt++; } void dfs(int u, int fa) { in[u]=++xx; idx[xx]=u; for (int i=head[u]; ~i; i=e[i].next) { int v=e[i].v; if (v==fa) continue; dis[v]=dis[u]+a[v]; dfs(v, u); } out[u]=xx; } void pushup(int id) { tree[id].val=tree[id*2].val+tree[id*2+1].val; tree[id].maxx=max(tree[id*2].maxx, tree[id*2+1].maxx); } void pushdown(int id) { if (tree[id].lazy) { tree[id*2].fun(tree[id].lazy); tree[id*2+1].fun(tree[id].lazy); tree[id].lazy=0; } } void build(int id, int l, int r) { tree[id].l=l, tree[id].r=r, tree[id].lazy=0; if (l==r) { tree[id].val=tree[id].maxx=dis[idx[l]]; } else { int mid=(l+r)/2; build(id*2, l, mid); build(id*2+1, mid+1, r); pushup(id); } } void updata(int id, int st, int ed, int val) { int l=tree[id].l, r=tree[id].r; if (st<=l&&r<=ed) tree[id].fun(val); else { pushdown(id); int mid=(l+r)/2; if (st<=mid) updata(id*2, st, ed, val); if (ed>mid) updata(id*2+1, st, ed, val); pushup(id); } } ll quary(int id, int st, int ed) { int l=tree[id].l, r=tree[id].r; if (st<=l&&r<=ed) return tree[id].maxx; else { pushdown(id); int mid=(l+r)/2; ll sum1=-inf, sum2=-inf; if (st<=mid) sum1=quary(id*2, st, ed); if (ed>mid) sum2=quary(id*2+1, st, ed); pushup(id); return max(sum1, sum2); } } void solve() { scanf("%d%d", &n, &m); init(); for (int i=0; i<n-1; i++) { int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } for (int i=0; i<n; i++) scanf("%d", a+i); dis[0]=a[0]; dfs(0, -1); build(1, 1, n); printf("Case #%d:\n", ca++); for (int i=0; i<m; i++) { int op, x; scanf("%d%d", &op, &x); if (!op) { int y; scanf("%d", &y); updata(1, in[x], out[x], y-a[x]); a[x]=y; } else { printf("%I64d\n", quary(1, in[x], out[x])); } } } int main() { int t = 1; //freopen("in.txt","r",stdin); // freopen("gcd.out","w",stdout); scanf("%d", &t); while(t--) solve(); return 0; }