P4114 Qtree1
题目描述
给定一棵n个节点的树,有两个操作:
- CHANGE i ti 把第i条边的边权变成ti
- QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0
码农题。
话说我码得变快了啊,虽然跟顾z吹45分钟码完Qtree没有完成,不过总共用了55分钟还是不长的嘿嘿。
code:
#include <iostream> #include <cstdio> #define ls(o) o<<1 #define rs(o) o<<1|1 #define int long long using namespace std; const int wx=500017; int head[wx],dfn[wx],size[wx],f[wx][23],dis[wx][23],dep[wx]; int son[wx],a[wx],top[wx],tid[wx]; int n,num,tot; char opt[17]; inline int read(){ int sum=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();} return sum*f; } /*~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~~~*/ struct e{ int nxt,to,dis; }edge[wx*2]; void add(int from,int to,int dis){ edge[++num].nxt=head[from]; edge[num].to=to; edge[num].dis=dis; head[from]=num; } int first_dfs(int u,int fa){ size[u]=1; int maxson=-1; dep[u]=dep[fa]+1; dis[u][0]=a[u]; f[u][0]=fa; for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(v==fa)continue; a[v]=edge[i].dis; first_dfs(v,u); size[u]+=size[v]; if(size[v]>maxson){ maxson=size[v]; son[u]=v; } } } int second_dfs(int u,int topf){ dfn[u]=++tot; top[u]=topf; tid[tot]=u; if(son[u])second_dfs(son[u],topf); for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(dfn[v]||v==f[u][0])continue; second_dfs(v,v); } } /*~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~ SGT~~~~~~~~~~~~~~~~~~~~~*/ struct SGT{ int l,r,tag,ma; #define tag(o) t[o].tag #define ma(o) t[o].ma }t[wx*4]; void up(int o){ ma(o)=max(ma(ls(o)),ma(rs(o))); } void down(int o){ if(tag(o)!=-1){ ma(ls(o))=tag(o); ma(rs(o))=tag(o); tag(ls(o))=tag(o); tag(rs(o))=tag(o); tag(o)=-1; } } void build(int o,int l,int r){ t[o].l=l; t[o].r=r; tag(o)=-1; if(l==r){ma(o)=a[tid[l]]; return ;} int mid=t[o].l+t[o].r>>1; if(l<=mid)build(ls(o),l,mid); if(r>mid)build(rs(o),mid+1,r); up(o); } void update_SGT(int o,int l,int r,int k){ if(l<=t[o].l&&t[o].r<=r){ ma(o)=k; tag(o)=k; return ; } down(o); int mid=t[o].l+t[o].r>>1; if(l<=mid)update_SGT(ls(o),l,r,k); if(r>mid)update_SGT(rs(o),l,r,k); up(o); } int query_SGT(int o,int l,int r){ if(l>r)return 0; if(l<=t[o].l&&t[o].r<=r){ return ma(o); } down(o); int maxn=-1; int mid=t[o].l+t[o].r>>1; if(l<=mid)maxn=max(maxn,query_SGT(ls(o),l,r)); if(r>mid)maxn=max(maxn,query_SGT(rs(o),l,r)); return maxn; } /*~~~~~~~~~~~~~~~~~ SGT~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~ LCA~~~~~~~~~~~~~~~~~~~~~*/ void pre(){ for(int j=1;j<=21;j++)for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1],dis[i][j]=max(dis[f[i][j-1]][j-1],dis[i][j-1]); } int find(int x,int y){ if(dep[x]<dep[y])swap(x,y); int re=-1; for(int i=21;i>=0;i--){ if(dep[f[x][i]]>=dep[y]){ re=max(re,dis[x][i]); x=f[x][i]; } } if(x==y)return re; for(int i=21;i>=0;i--){ if(f[x][i]!=f[y][i]){ re=max(re,max(dis[x][i],dis[y][i])); x=f[x][i]; y=f[y][i]; } } return max(re,max(dis[x][0],dis[y][0])); } int LCA(int x,int y){ if(dep[x]<dep[y])swap(x,y); for(int i=21;i>=0;i--){ if(dep[f[x][i]]>=dep[y]){ x=f[x][i]; } } if(x==y)return x; for(int i=21;i>=0;i--){ if(f[x][i]!=f[y][i]){ x=f[x][i]; y=f[y][i]; } } return f[x][0]; } /*~~~~~~~~~~~~~~~~~ LCA~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~ shu pou~~~~~~~~~~~~~~~~~*/ void update(int x,int y,int k){ int fx=top[x]; int fy=top[y]; while(fx!=fy){ if(dep[fx]>=dep[fy])update_SGT(1,dfn[fx],dfn[x],k),x=f[fx][0]; else update_SGT(1,dfn[fy],dfn[y],k),y=f[fy][0]; fx=top[x]; fy=top[y]; } if(dfn[x]>dfn[y])swap(x,y); update_SGT(1,dfn[x],dfn[y],k); } int query(int x,int y){ int fx=top[x]; int fy=top[y]; int re=-1; while(fx!=fy){ if(dep[fx]>=dep[fy])re=max(re,query_SGT(1,dfn[fx],dfn[x])),x=f[fx][0]; else re=max(re,query_SGT(1,dfn[fy],dfn[y])),y=f[fy][0]; fx=top[x]; fy=top[y]; } if(dfn[x]>dfn[y])swap(x,y); re=max(re,query_SGT(1,dfn[x],dfn[y])); return re; } /*~~~~~~~~~~~~~~~~~ shu pou~~~~~~~~~~~~~~~~~*/ signed main(){ n=read(); for(int i=1;i<n;i++){ int x,y,z; x=read(); y=read(); z=read(); add(x,y,z); add(y,x,z); } first_dfs(1,0); second_dfs(1,1); build(1,1,n); pre(); while(1){ scanf("%s",opt+1); if(opt[1]=='D')break; if(opt[1]=='Q'){ int x,y; x=read(); y=read(); if(x==y)puts("0"); else{ int lca=LCA(x,y); int tmp=query_SGT(1,dfn[lca],dfn[lca]); update_SGT(1,dfn[lca],dfn[lca],-521); printf("%lld\n",query(x,y)); update_SGT(1,dfn[lca],dfn[lca],tmp); } } if(opt[1]=='C'){ int x,y; x=read(); y=read(); int x1=edge[x*2-1].to; int x2=edge[x*2].to; if(dep[x1]>dep[x2])x=x1; else x=x2; update(x,x,y); } } return 0; } /* 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE */
来源:https://www.cnblogs.com/wangxiaodai/p/9858816.html