bzoj2588 -- 树链剖分+主席树
来源:互联网 发布:手机虚拟试衣软件 编辑:程序博客网 时间:2024/05/29 03:47
先将权值离散。
显然可以对于每个结点建一棵权值线段树存这个点到根结点的路径上的点权,询问时在线段树上二分,但这样时间是O(n2logn)的。
然后想到用主席树优化,时间复杂度O(n*log n)。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define ll long long 8 inline char nc(){ 9 static char buf[100000],*p1=buf,*p2=buf;10 if(p1==p2){11 p2=(p1=buf)+fread(buf,1,100000,stdin);12 if(p1==p2)return EOF;13 }14 return *p1++;15 }16 inline void Read(int& x){17 char c=nc(),b=1;18 for(;c<'0'||c>'9';c=nc())if(c=='-')b=-1;19 for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());x*=b;20 }21 char S[30];22 int Len;23 inline void Print(int x){24 for(Len=0;x;x/=10)S[++Len]=x%10;25 while(Len)putchar(S[Len--]+48);26 }27 #define N 10001028 vector<int>g[N];29 struct Ls{30 int w,f;31 }l[N];32 struct Node{33 int l,r,s;34 }c[N*80];35 int Ans,i,j,k,n,m,x,y,a[N],Top[N],Rt[N],f[N],d[N],s[N],Son[N],w[N],Num,Cnt,L;36 inline void Dfs1(int x,int F){37 f[x]=F;d[x]=d[F]+1;s[x]=1;38 for(int i=0;i<g[x].size();i++)39 if(g[x][i]!=F){40 Dfs1(g[x][i],x);41 if(s[g[x][i]]>s[Son[x]])Son[x]=g[x][i];42 s[x]+=s[g[x][i]];43 }44 }45 inline void Insert(int Last,int& x,int l,int r,int y){46 c[++Cnt]=c[Last];47 x=Cnt;c[x].s++;48 if(l==r)return;49 int Mid=l+r>>1;50 if(Mid>=y)Insert(c[Last].l,c[x].l,l,Mid,y);else Insert(c[Last].r,c[x].r,Mid+1,r,y);51 }52 inline void Dfs2(int x,int Tmp){53 Top[x]=Tmp;Insert(Rt[f[x]],Rt[x],1,Num,a[x]);54 if(Son[x])Dfs2(Son[x],Tmp);55 for(int i=0;i<g[x].size();i++)56 if(g[x][i]!=f[x]&&g[x][i]!=Son[x])Dfs2(g[x][i],g[x][i]);57 }58 inline bool Cmp(Ls a,Ls b){return a.w<b.w;}59 inline int Lca(int x,int y){60 while(Top[x]!=Top[y])61 if(d[Top[x]]>d[Top[y]])x=f[Top[x]];else y=f[Top[y]];62 return d[x]>d[y]?y:x;63 }64 inline int Query(int x,int y,int z,int p,int l,int r,int k){65 if(l==r)return l;66 int Mid=l+r>>1;67 int S=k-c[c[x].l].s-c[c[y].l].s+c[c[z].l].s+c[c[p].l].s;68 if(S<=0)return Query(c[x].l,c[y].l,c[z].l,c[p].l,l,Mid,k);69 return Query(c[x].r,c[y].r,c[z].r,c[p].r,Mid+1,r,S);70 }71 int main(){72 Read(n);Read(m);73 for(i=1;i<=n;i++)Read(l[i].w),l[i].f=i;74 sort(l+1,l+n+1,Cmp);75 a[l[1].f]=Num=1;w[1]=l[1].w;76 for(i=2;i<=n;i++)77 if(l[i].w==l[i-1].w)a[l[i].f]=Num;else a[l[i].f]=++Num,w[Num]=l[i].w;78 for(i=1;i<n;i++)Read(x),Read(y),g[x].push_back(y),g[y].push_back(x);79 Dfs1(1,0);Dfs2(1,1);80 while(m--){81 Read(x);Read(y);Read(k);82 x^=Ans;83 L=Lca(x,y);84 Ans=w[Query(Rt[x],Rt[y],Rt[L],Rt[f[L]],1,Num,k)];85 Print(Ans);86 if(m)putchar('\n');87 }88 return 0;89 }
阅读全文
0 0
- bzoj2588 -- 树链剖分+主席树
- bzoj2588树上主席树
- BZOJ2588 主席树
- bzoj2588 count on a tree 主席树
- 【bzoj2588】Count on a tree 主席树
- [bzoj2588][主席树]Count on a tree
- bzoj2588 Count on a tree dfs&主席树
- 【bzoj2588】Spoj 10628. Count on a tree LCA+主席树
- 【BZOJ2588】Spoj 10628. Count on a tree【主席树】【LCA】
- [主席树] BZOJ2588: Spoj 10628. Count on a tree
- BZOJ2588 Count on a tree 【树上主席树】
- [BZOJ2588][Spoj10628]Count on a tree(树上主席树)
- 【BZOJ2588】Count On a Tree(主席树)
- [BZOJ2588]Count on a tree(可持久化权值线段树|主席树)
- bzoj2588:Spoj 10628. Count on a tree(树套主席树)
- bzoj2588: Spoj 10628. Count on a tree 主席树+dfs序
- 【BZOJ2588】Count on a tree,主席树维护链+ST表求LCA
- BZOJ2588 Count on a tree <DFS序+LCA+值域主席树>
- bzoj2120&&2453 -- 带修改莫队
- bzoj4546 -- 可持久化字典树
- bzoj4712 -- 树链剖分
- SpringMVC用PropertyPlaceholderConfigurer读取配置文件
- Oracle数字函数
- bzoj2588 -- 树链剖分+主席树
- bzoj4881 [ Lydsy2017年5月月赛 ] -- 二分图染色+线段树
- bzoj2165 -- 倍增floyd
- bzoj3626 [ LNOI2014 ] -- 树链剖分
- POJ2104_K-th Number_归并树|二分 ||平方分割的分桶法|二分
- SVN导下来Maven工程就报错 org.apache.ibatis.binding.BindingException
- bzoj1857 [ SCOI2010 ] -- 三分套三分
- WampServer 中Apache配置别名访问
- 三国历史脉络图