BZOJ 2243 树链剖分+线段树

    xiaoxiao2021-03-25  74

    #include <bits/stdc++.h> #define N 101000 #define FREI freopen("in.txt","r",stdin) #define FREO freopen("out.txt","w",stdout) #define Mem(a,b) memset(a,b,sizeof(a)) #define lson root<<1 #define rson root<<1|1 #define Mid int mid=(l+r)>>1 #define inf 0x3f3f3f3f using namespace std; int n,m,k,siz[N],fa[N],son[N],cnt,f[N],invf[N],dep[N],tp[N],ecnt,ans,res,rr; int node[N]; struct edge { int v,next; }; edge e[N<<2]; int head[N],mark[N<<2]; struct tree { int l,r,cnt; }; tree seg[N<<2]; void add(int u,int v) { e[ecnt]=(edge) { v,head[u] }; head[u]=ecnt++; } void initsplit(){ Mem(head,-1); dep[1]=0; Mem(son,-1); Mem(mark,-1); ecnt=cnt=0; } void dfs1(int u,int father) { dep[u]=dep[father]+1; fa[u]=father; siz[u]=1; for(int i=head[u]; ~i; i=e[i].next) { int v=e[i].v; if(v!=father) { dfs1(v,u); siz[u]+=siz[v]; if(son[u]==-1||siz[son[u]]<siz[v]) son[u]=v; } } } void dfs2(int u,int top) { tp[u]=top; f[u]=++cnt; invf[f[u]]=u; if(son[u]==-1) return ; dfs2(son[u],top); for(int i=head[u]; ~i; i=e[i].next) { int v=e[i].v; if(v!=son[u]&&v!=fa[u]) { dfs2(v,v); } } } void push_down(int root,int l,int r) { if(~mark[root]) { mark[lson]=mark[rson]=mark[root]; seg[lson].cnt=seg[rson].cnt=1; seg[lson].l=seg[lson].r=seg[rson].l=seg[rson].r=mark[root]; mark[root]=-1; } } void push_up(int root,int l,int r) { seg[root].cnt=seg[lson].cnt+seg[rson].cnt; if(seg[lson].r==seg[rson].l) seg[root].cnt--; seg[root].l=seg[lson].l; seg[root].r=seg[rson].r; } void build(int root,int l,int r) { if(l==r) { seg[root].cnt=1; seg[root].l=seg[root].r=node[invf[l]]; return ; } Mid; build(lson,l,mid); build(rson,mid+1,r); push_up(root,l,r); } void update(int root,int l,int r,int ql,int qr,int val) { if(l>qr||r<ql) return; if(l>=ql&&r<=qr) { seg[root].cnt=1; seg[root].l=seg[root].r=val; mark[root]=val; return ; } Mid; push_down(root,l,r); update(lson,l,mid,ql,qr,val); update(rson,mid+1,r,ql,qr,val); push_up(root,l,r); } void query(int root,int l,int r,int ql,int qr) { if(l>qr||r<ql) return; if(l>=ql&&r<=qr) { if(!ans) { ans=seg[root].cnt; rr=seg[root].r; return; } ans+=seg[root].cnt; if(rr==seg[root].l) ans--; rr=seg[root].r; return ; } Mid; push_down(root,l,r); query(lson,l,mid,ql,qr); query(rson,mid+1,r,ql,qr); push_up(root,l,r); } int cloquer(int root,int l,int r,int ql,int qr) { int tmp=0; if(l>qr||r<ql) return 0; if(l>=ql&&r<=qr) { return seg[root].l; } Mid; push_down(root,l,r); tmp+=cloquer(lson,l,mid,ql,qr); tmp+=cloquer(rson,mid+1,r,ql,qr); push_up(root,l,r); return tmp; } int main() { //FREI; //FREO; while(scanf("%d%d",&n,&m)!=EOF) { initsplit(); for(int i=1; i<=n; i++) scanf("%d",&node[i]); for(int i=1; i<n; i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs1(1,1); dfs2(1,1); build(1,1,n); for(int i=0; i<m; i++) { char x[10]; scanf("%s",x); if(x[0]=='Q') { int x,y; scanf("%d%d",&x,&y); res=0; while(tp[x]!=tp[y]) { if(dep[tp[x]]<dep[tp[y]]) swap(x,y); ans=0; query(1,1,n,f[tp[x]],f[x]); res+=ans; if(cloquer(1,1,n,f[tp[x]],f[tp[x]])==cloquer(1,1,n,f[fa[tp[x]]],f[fa[tp[x]]])) res--; x=fa[tp[x]]; } if(dep[x]>dep[y]) swap(x,y); ans=0; query(1,1,n,f[x],f[y]); res+=ans; printf("%d\n",res); } else { int x,y,val; scanf("%d%d%d",&x,&y,&val); while(tp[x]!=tp[y]) { if(dep[tp[x]]<dep[tp[y]]) swap(x,y); update(1,1,n,f[tp[x]],f[x],val); x=fa[tp[x]]; } if(dep[x]>dep[y]) swap(x,y); update(1,1,n,f[x],f[y],val); } } } } 变量命名是关键啊  很早写完改好了 一直出错 原来是函数体里的一个变量和全局变量重名了 一直没发现 好累 浪费了超多的时间  好好注意
    转载请注明原文地址: https://ju.6miu.com/read-25507.html

    最新回复(0)