BZOJ2588: Spoj 10628. Count on a tree
2016-12-09 12:56
375 查看
传送门
刚开始看错题以为是dfs序瞎搞..
后来看清题了开始想用树剖瞎搞...
感觉要滚粗啊..
对于每个点到根的路径建立线段树,暴力建MLE没跑,上主席树,然后$(x,y)$的路径就可以先求出来$LCA$,然后就可以用$T_x+T_y-T_{LCA}-T_{fa[LCA]}$就行了。
刚开始看错题以为是dfs序瞎搞..
后来看清题了开始想用树剖瞎搞...
感觉要滚粗啊..
对于每个点到根的路径建立线段树,暴力建MLE没跑,上主席树,然后$(x,y)$的路径就可以先求出来$LCA$,然后就可以用$T_x+T_y-T_{LCA}-T_{fa[LCA]}$就行了。
//BZOJ 2588 //by Cydiater //2016.12.8 #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <iomanip> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <ctime> #include <bitset> #include <set> #include <vector> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) #define cmax(a,b) a=max(a,b) #define cmin(a,b) a=min(a,b) #define Auto(i,node) for(int i=LINK[node];i;i=e[i].next) const int MAXN=1e5+5; const int oo=0x3f3f3f3f; inline int read(){ char ch=getchar();ll x=0,f=1; while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int N,M,dfn[MAXN],dfs_clock=0,fsort[MAXN],val[MAXN],root[MAXN],rnum=0,cnt=0,fa[MAXN][25],ans=0; struct Graph{ int LINK[MAXN],len,dep[MAXN]; struct edge{ int y,next; }e[MAXN<<1]; inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;} inline void Insert(int x,int y){insert(x,y);insert(y,x);} void make_graph(){ N=read();M=read(); up(i,1,N)val[i]=fsort[i]=read(); sort(fsort+1,fsort+N+1); rnum=unique(fsort+1,fsort+N+1)-(fsort+1); up(i,1,N)val[i]=lower_bound(fsort+1,fsort+rnum+1,val[i])-fsort; up(i,1,N-1){ int x=read(),y=read(); Insert(x,y); } } void dfs(int node,int deep,int father){ dfn[++dfs_clock]=node; dep[node]=deep;fa[node][0]=father; Auto(i,node)if(e[i].y!=father) dfs(e[i].y,deep+1,node); } void set_anc(){ up(i,1,20)up(node,1,N) if(fa[node][i-1])fa[node][i]=fa[fa[node][i-1]][i-1]; } int LCA(int x,int y){ if(x==y) return x; if(dep[x]<dep[y]) swap(x,y); down(i,20,0)if(dep[x]-(1<<i)>=dep[y])x=fa[x][i]; if(x==y) return x; down(i,20,0)if(fa[x][i]!=0&&fa[x][i]!=fa[y][i]){ x=fa[x][i]; y=fa[y][i]; } return fa[x][0]; } }G; struct Chair_man_Tree{ int son[2],sum; }t[MAXN<<5]; namespace solution{ int NewNode(int sum,int son0,int son1){ t[++cnt].sum=sum;t[cnt].son[0]=son0;t[cnt].son[1]=son1; return cnt; } void insert(int leftt,int rightt,int &Root,int last,int pos){ Root=NewNode(t[last].sum+1,t[last].son[0],t[last].son[1]); int mid=(leftt+rightt)>>1; if(leftt==rightt) return; if(pos<=mid) insert(leftt,mid,t[Root].son[0],t[last].son[0],pos); else insert(mid+1,rightt,t[Root].son[1],t[last].son[1],pos); } void Prepare(){ G.make_graph(); G.dfs(1,0,0); G.set_anc(); up(i,1,N){ int node=dfn[i],father=fa[node][0],pos=val[node]; insert(1,rnum,root[node],root[father],pos); } } int Get(int leftt,int rightt,int rx,int ry,int rlca,int rflca,int rnk){ int sum=t[t[rx].son[0]].sum+t[t[ry].son[0]].sum-t[t[rlca].son[0]].sum-t[t[rflca].son[0]].sum; if(leftt==rightt) return fsort[leftt]; int mid=(leftt+rightt)>>1; if(rnk<=sum) return Get(leftt,mid,t[rx].son[0],t[ry].son[0],t[rlca].son[0],t[rflca].son[0],rnk); else return Get(mid+1,rightt,t[rx].son[1],t[ry].son[1],t[rlca].son[1],t[rflca].son[1],rnk-sum); } void Slove(){ while(M--){ int x=read()^ans,y=read(),k=read(),lca=G.LCA(x,y); printf("%d",ans=Get(1,rnum,root[x],root[y],root[lca],root[fa[lca][0]],k)); if(M)puts(""); } } } int main(){ //freopen("input.in","r",stdin); using namespace solution; Prepare(); Slove(); return 0; }
相关文章推荐
- BZOJ2588: Spoj 10628. Count on a tree
- BZOJ2588: Spoj 10628. Count on a tree
- bzoj2588 Spoj 10628. Count on a tree
- bzoj2588: Spoj 10628. Count on a tree
- bzoj2588 Spoj 10628. Count on a tree
- bzoj2588 Spoj 10628. Count on a tree
- BZOJ2588: Spoj 10628. Count on a tree
- 【BZOJ2588】Spoj 10628. Count on a tree【主席树】【LCA】
- BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
- BZOJ-2588-Count-on-a-tree-SPOJ10628-LCA+主席树
- BZOJ 2588: Spoj 10628. Count on a tree | 树上主席树
- bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)
- 【bzoj2588】Spoj 10628. Count on a tree
- BZOJ 2588: Spoj 10628. Count on a tree
- [主席树] BZOJ2588: Spoj 10628. Count on a tree
- 【BZOJ 2588】 Spoj 10628. Count on a tree|树上K大|树链剖分|主席树
- 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)
- BZOJ2588 Spoj 10628. Count on a tree
- bzoj 2588: Spoj 10628. Count on a tree【主席树+倍增】
- spoj 10628 Count on a tree