【bzoj4551】TJOI2016&HEOI2016树
这题嘛……
子树询问什么的,直接dfs序线段树无脑写,是吧……
然后几分钟之内zcy就写出了这样的东西:
#include<bits/stdc++.h> #define N 100005 #define lson (o<<1) #define rson (o<<1|1) using namespace std; int n,m,cnt,tot,head[N],a[N]; struct Edge{int u,v,next;}G[N<<1]; int lpos[N],rpos[N],d[N],fa[N]; inline void addedge(int u,int v){ G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot; G[++tot].u=v;G[tot].v=u;G[tot].next=head[v];head[v]=tot; } void dfs(int u,int f){ lpos[u]=++cnt; for(int i=head[u];i;i=G[i].next){ int v=G[i].v;if(v==f)continue; fa[v]=u;d[v]=d[u]+1; dfs(v,u); } rpos[u]=cnt; } inline int mmp(int x,int y){return d[x]>d[y]?x:y;} struct Segment_Tree{ int tagv[N<<2],maxv[N<<2]; inline void pushup(int o){maxv[o]=max(maxv[lson],maxv[rson]);} inline void puttag(int o,int x){tagv[o]=mmp(tagv[o],x);maxv[o]=mmp(maxv[o],x);} inline void pushdown(int o){ if(!tagv[o])return; puttag(lson,tagv[o]);puttag(rson,tagv[o]); tagv[o]=0; } void build(int o,int l,int r){ tagv[o]=0;maxv[o]=1;if(l==r)return; int mid=(l+r)>>1; build(lson,l,mid);build(rson,mid+1,r); } void change(int o,int l,int r,int ql,int qr,int v){ if(ql<=l&&r<=qr){puttag(o,v);return;} int mid=(l+r)>>1;pushdown(o); if(ql<=mid)change(lson,l,mid,ql,qr,v); if(qr>mid)change(rson,mid+1,r,ql,qr,v); pushup(o); } int querymax(int o,int l,int r,int q){ if(l==r)return maxv[o]; int mid=(l+r)>>1;pushdown(o); if(q<=mid)return querymax(lson,l,mid,q); if(q>mid)return querymax(rson,mid+1,r,q); } }T; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ n=read();m=read(); for(int i=1;i<n;i++){ int u=read(),v=read(); addedge(u,v); } dfs(1,0);T.build(1,1,n); char s[20]; while(m--){ scanf("%s",s);int x=read(); if(s[0]=='C')T.change(1,1,n,lpos[x],rpos[x],x); else printf("%d\n",T.querymax(1,1,n,lpos[x])); } }
对于sb的我来说,写这种模版最快不过了……
在真正的省选考场上,写这种东西的选手恐怕也是最多,写起来也是最稳的吧……
然而其实还有一种O(na(n))的做法吊打我。
就是巧妙地离线用并查集维护标记,当作连通性维护……
orz
反正要是我去省选怕是想不出的吧……
#include<bits/stdc++.h> #define N 100005 using namespace std; int n,m,tot,head[N],c[N],a[N],fa[N],f[N],ans[N]; char s[N]; struct Edge{int u,v,next;}G[N<<1]; inline void addedge(int u,int v){ G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot; G[++tot].u=v;G[tot].v=u;G[tot].next=head[v];head[v]=tot; } int find(int x){return x==f[x]?x:f[x]=find(f[x]);} void dfs(int u){ f[u]=c[u]?u:fa[u]; for(int i=head[u];i;i=G[i].next){ int v=G[i].v;if(v!=fa[u])fa[v]=u,dfs(v); } } inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ n=read();m=read(); for(int i=1;i<n;i++){ int u=read(),v=read(); addedge(u,v); }c[1]=1; for(int i=1;i<=m;i++){ do{s[i]=getchar();}while(s[i]!='C'&&s[i]!='Q'); a[i]=read(); if(s[i]=='C')c[a[i]]++; } dfs(1); for(int i=m;i;i--){ if(s[i]=='C'){c[a[i]]--;if(!c[a[i]])f[a[i]]=fa[a[i]];} else ans[i]=find(a[i]); } for(int i=1;i<=m;i++)if(ans[i])printf("%d\n",ans[i]); }
zzq wc-ctsc-apio-NOI Au;yql精通多项式;zyz精通女装;由乃精通数据结构;孔老师是毒奶大师;我没有学上:我们都有光明的前途。