标签:led inf include ack cst void 参考 printf 编号
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input4 1 2 2 3 4 1 4 2 1 3 12 QMAX 3 4 QMAX 3 3 QMAX 3 2 QMAX 2 3 QSUM 3 4 QSUM 2 1 CHANGE 1 5 QMAX 3 4 CHANGE 3 6 QMAX 3 4 QMAX 2 4 QSUM 3 4Sample Output4 1 2 2 10 6 5 6 5 16Hint
树链剖分+线段树模板题:
参考代码:
#include<cstdio> #include<cstring> #include<string> #include<cmath> #include<iostream> #include<algorithm> #include<queue> #include<cstdlib> #include<stack> #include<vector> #include<set> #include<map> #define LL long long #define mod 10007 #define inf 0x3f3f3f3f #define N 100010 #define FILL(a,b) (memset(a,b,sizeof(a))) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; struct edge { int to,next; edge(){} edge(int to,int next):to(to),next(next){} }e[N<<1]; int head[N<<1],tot,top[N],fa[N]; int dep[N],sz[N],son[N],p[N],fp[N];//fp与相反 int pos;//所有链构成线段树的总长度 int sum[N<<2],mx[N<<2],a[N]; void addedge(int u,int v) { e[tot]=edge(v,head[u]); head[u]=tot++; } void init() { tot=0; FILL(head,-1); pos=0; FILL(son,-1); } void dfs(int u,int f,int d) { dep[u]=d;sz[u]=1;fa[u]=f; for(int i=head[u];~i;i=e[i].next) { int v=e[i].to; if(v==f)continue; dfs(v,u,d+1); sz[u]+=sz[v]; if(son[u]==-1||sz[son[u]]<sz[v]) son[u]=v; } } void getpos(int u,int sp) { top[u]=sp; p[u]=++pos; fp[pos]=u; if(son[u]==-1) return; getpos(son[u],sp); for(int i=head[u];~i;i=e[i].next) { int v=e[i].to; if(v!=son[u] && v!=fa[u]) getpos(v,v); } } void Pushup(int rt) { int ls=rt<<1,rs=ls|1; sum[rt]=sum[ls]+sum[rs]; mx[rt]=max(mx[ls],mx[rs]); } void build(int l,int r,int rt) { if(l==r) { mx[rt]=sum[rt]=a[fp[l]]; return; } int m=(l+r)>>1; build(lson),build(rson); Pushup(rt); } void update(int ps,int c,int l,int r,int rt) { if(l==r) { mx[rt]=sum[rt]=c; return; } int m=(l+r)>>1; if(ps<=m) update(ps,c,lson); else update(ps,c,rson); Pushup(rt); } int querysum(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return sum[rt]; int m=(l+r)>>1; int res=0; if(L<=m) res+=querysum(L,R,lson); if(R>m) res+=querysum(L,R,rson); return res; } int querymax(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return mx[rt]; int m=(l+r)>>1; int res=-inf; if(L<=m) res=max(res,querymax(L,R,lson)); if(m<R) res=max(res,querymax(L,R,rson)); return res; } int lca(int u,int v,int flag) { int fu=top[u],fv=top[v],res; if(flag) res=-inf; else res=0; while(fu!=fv) { if(dep[fu]<dep[fv]) swap(fu,fv),swap(u,v); if(flag) res=max(res,querymax(p[fu],p[u],1,pos,1)); else res+=querysum(p[fu],p[u],1,pos,1); u=fa[fu];fu=top[u]; } if(dep[u]>dep[v]) swap(u,v); if(flag) res=max(res,querymax(p[u],p[v],1,pos,1)); else res+=querysum(p[u],p[v],1,pos,1); return res; } int main() { int n,t,u,v,w; char op[10]; while(scanf("%d",&n)>0) { init(); for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } for(int i=1;i<=n;i++) scanf("%d",&a[i]); dfs(1,0,0); getpos(1,1); build(1,pos,1); scanf("%d",&t); while(t--) { scanf("%s",op); scanf("%d%d",&u,&v); if(op[1]==‘S‘) printf("%d\n",lca(u,v,0)); else if(op[1]==‘M‘) printf("%d\n",lca(u,v,1)); else update(p[u],v,1,pos,1); } } return 0; }
标签:led inf include ack cst void 参考 printf 编号
原文地址:https://www.cnblogs.com/songorz/p/9704379.html