您的位置:首页 > 其它

主席树初探--BZOJ2588: Spoj 10628. Count on a tree

2017-11-30 07:14 489 查看

n<=100000的点权树,有m<=100000个询问,每次问两个点间的第k小点权,保证有解,强制在线。

主席上树啦!类似于之前的序列不带修改询问的前缀表示法,现在只要把前缀当成某点到根的信息即可。然后比如要问x点和y点,z为lca(x,y),w为z的爸爸,那么x,y,z,w四棵线段树一起跑即可。

1 #include<stdio.h>
2 #include<string.h>
3 #include<algorithm>
4 #include<stdlib.h>
5 //#include<iostream>
6 using namespace std;
7
8 int n,m;
9 #define maxn 100011
10 #define maxm 2000011
11 struct SMT
12 {
13     struct Node
14     {
15         int son[2];
16         int cnt;
17     }a[maxm];
18     int size,n;
19     void clear(int m) {n=m;size=0;a[0].cnt=0;}
20     void build(int pre,int &rt,int L,int R,int num)
21     {
22         rt=++size;
23         a[rt].cnt=a[pre].cnt+1;
24         if (L==R) {a[rt].son[0]=a[rt].son[1]=0;return;}
25         const int mid=(L+R)>>1;
26         if (num<=mid) build(a[pre].son[0],a[rt].son[0],L,mid,num),a[rt].son[1]=a[pre].son[1];
27         else build(a[pre].son[1],a[rt].son[1],mid+1,R,num),a[rt].son[0]=a[pre].son[0];
28     }
29     void build(int pre,int &rt,int num) {build(pre,rt,1,n,num);}
30 //    void test(int x,int L,int R)
31 //    {
32 //        const int mid=(L+R)>>1;
33 //        if (a[x].son[0]) test(a[x].son[0],L,mid);
34 ////        cout<<L<<' '<<R<<' '<<a[x].cnt<<endl;
35 //        if (a[x].son[1]) test(a[x].son[1],mid+1,R);
36 //    }
37 //    void test(int x) {test(x,1,n);}
38 }smt;
39
40 struct Edge{int to,next;}edge[maxn<<1];int first[maxn],le=2;
41 void in(int x,int y) {Edge &e=edge[le];e.to=y;e.next=first[x];first[x]=le++;}
42 void insert(int x,int y) {in(x,y);in(y,x);}
43
44 int a[maxn],b[maxn],lb;
45 int fa[maxn][22],dep[maxn],rt[maxn];
46 void dfs(int x,int f)
47 {
48     fa[x][0]=f;dep[x]=dep[f]+1;
49     for (int j=1;j<=18;j++)
50         fa[x][j]=fa[fa[x][j-1]][j-1];
51     smt.build(rt[f],rt[x],a[x]);
52     for (int i=first[x];i;i=edge[i].next)
53     {
54         const Edge &e=edge[i];if (e.to==f) continue;
55         dfs(e.to,x);
56     }
57 }
58 void pre() {dfs(1,0);}
59
60 int lca(int x,int y)
61 {
62     if (dep[x]<dep[y]) {int t=x;x=y;y=t;}
63     for (int i=18;i>=0;i--) if (dep[fa[x][i]]>=dep[y]) x=fa[x][i];
64     if (x==y) return x;
65     for (int i=18;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
66     return fa[x][0];
67 }
68
69 int main()
70 {
71     scanf("%d%d",&n,&m);
72     for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
73     lb=n;sort(b+1,b+1+lb);lb=unique(b+1,b+1+lb)-b-1;
74     for (int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+lb,a[i])-b;
75
76     smt.clear(lb);
77     for (int i=1,x,y;i<n;i++)
78     {
79         scanf("%d%d",&x,&y);
80         insert(x,y);
81     }
82     pre();
83 //    for (int i=1;i<=n;i++) smt.test(rt[i]),cout<<endl;
84     int last=0;
85     for (int i=1,x,y,K;i<=m;i++)
86     {
87         scanf("%d%d%d",&x,&y,&K);
88         x^=last;
89         int z=lca(x,y),w=fa[z][0],L=1,R=lb,tmp;
90 //        cout<<x<<' '<<y<<' '<<z<<' '<<w<<endl;
91         x=rt[x];y=rt[y];z=rt[z];w=rt[w];
92         while (L<R)
93         {
94             if ((tmp=smt.a[smt.a[x].son[0]].cnt+smt.a[smt.a[y].son[0]].cnt
95             -smt.a[smt.a[z].son[0]].cnt-smt.a[smt.a[w].son[0]].cnt)>=K)
96                 x=smt.a[x].son[0],y=smt.a[y].son[0],z=smt.a[z].son[0],w=smt.a[w].son[0],R=(L+R)>>1;
97             else x=smt.a[x].son[1],y=smt.a[y].son[1],z=smt.a[z].son[1],w=smt.a[w].son[1],K-=tmp,L=((L+R)>>1)+1;
98 //            cout<<tmp<<' '<<K<<endl;
99         }
100         printf("%d",(last=b[L]));
101         if (i<m) puts("");
102     }
103     return 0;
104 }
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: