比较水的题了,比模板题还要简单一点
理解了这个结构,自己打出来的,但是小错误还是很多,越来越熟练吧希望
错误函数updata,updata_lca,query||错误地方区间往下递归的时候是left <= mid || right > mid
//https://vjudge.net/contest/251031#problem #include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #include <cmath> #define lson rt<<1,left,mid #define rson rt<<1|1,mid+1,right #define ls rt<<1 #define rs rt<<1|1 //#define mid ((left + right) >> 1) using namespace std; typedef long long ll; const int maxn = 1e5 + 1e3; int n,m,p; int V[maxn]; //邻接表 struct node{ int to,pre; }e[maxn << 1]; int id[maxn],cnt; //线段树 int val[maxn << 2],lazy[maxn<<2]; //dfs1 int siz[maxn],dep[maxn],fa[maxn],son[maxn]; //dfs2 int top[maxn],num_id[maxn],id_num[maxn]; int tot; void init() { memset(id,-1,sizeof(id)); memset(son,0,sizeof(son)); cnt = tot = 0; } void add(int from,int to) { e[cnt].to = to; e[cnt].pre = id[from]; id[from] = cnt++; } void dfs1(int now,int f,int depth) { siz[now] = 1; fa[now] = f; dep[now] = depth; for(int i = id[now];~i;i = e[i].pre) { int to = e[i].to; if(to != f) { dfs1(to,now,depth+1); siz[now] += siz[to]; if(siz[to] > siz[son[now]]) son[now] = to; } } } void dfs2(int now,int rt) { top[now] = rt; num_id[now] = ++tot; id_num[tot] = now; if(!son[now]) return; dfs2(son[now],rt); for(int i = id[now];~i;i = e[i].pre) { int to = e[i].to; if(to != son[now] && to != fa[now]) { dfs2(to,to); } } } void pup(int rt) { val[rt] = val[ls] + val[rs]; } void build(int rt,int left,int right) { lazy[rt] = 0; if(left == right) { val[rt] = V[id_num[left]]; return; } int mid = (left + right) >> 1; build(lson);build(rson); pup(rt); } void pdown(int rt,int left,int right) { if(lazy[rt]) { int lt = lazy[rt]; int mid = (left + right) >> 1; val[ls] += (mid - left + 1) * lt; val[rs] += (right - mid) * lt; lazy[rs] += lt; lazy[ls] += lt; lazy[rt] = 0; } } void updata(int rt,int left,int right,int l,int r,int k) { if(left > r || right < l)return; if(l <= left && right <= r) { val[rt] += (right - left + 1) * k; lazy[rt] += k; return; } pdown(rt,left,right); int mid = (left + right) >> 1; if(left <= mid) updata(lson,l,r,k); if(right > mid) updata(rson,l,r,k); } void updata_lca(int x,int y,int k) { while(top[x] != top[y]) { if(dep[top[x]] < dep[top[y]])swap(x,y); updata(1,1,tot,num_id[top[x]],num_id[x],k); x = fa[top[x]]; } if(dep[x] < dep[y])swap(x,y); updata(1,1,tot,num_id[y],num_id[x],k); } int query(int rt,int left,int right,int l,int r) { int res = 0; if(left > r || right < l)return 0; if(l <= left && right <= r) { return val[rt]; } pdown(rt,left,right); int mid = (left + right) >> 1; if(left <= mid)res += query(lson,l,r); if(right > mid)res += query(rson,l,r); return res; } int main() { while(~scanf("%d%d%d",&n,&m,&p)) { init(); for(int i = 1;i <= n;++i) { scanf("%d",&V[i]); } int from,to; for(int i = 1;i <= m;++i) { scanf("%d%d",&from,&to); add(from,to); add(to,from); } dfs1(1,1,1); //忘记init dfs2(1,1); build(1,1,tot); //cout<<val[1]<<" "<<val[2]<<" "<<val[3]<<" "<<val[4]<<" "<<val[5]<<endl;正确建树 char op[2]; int x,y,z; for(int i = 0;i < p;++i) { scanf("%s",op); if(op[0] == 'I') { scanf("%d%d%d",&x,&y,&z); updata_lca(x,y,z); } else if(op[0] == 'D') { scanf("%d%d%d",&x,&y,&z); //cout<<num_id[x]<<" "<<num_id[y]<<endl; updata_lca(x,y,-z); } else { scanf("%d",&x); //cout<<num_id[x]<<endl;对 printf("%d ",query(1,1,tot,num_id[x],num_id[x])); } } } return 0; } /* 3 2 500 1 2 3 2 1 2 3 */