# Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

## 2588: Spoj 10628. Count on a tree

Time Limit: 12 Sec  Memory Limit: 128 MB
Submit: 3584  Solved: 835
[Submit][Status][Discuss]

M行，表示每个询问的答案。

## Sample Input

8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2

2
8
9
105
7

HINT：

N,M<=100000

## Source

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define MAXN 100010
4 struct node
5 {
6     int begin,end,next;
7 }edge[MAXN*2];
8 struct NODE
9 {
10     int left,right;
11 }tree[MAXN*20];
13 bool vis[MAXN];
15 {
17 }
19 {
21 }
23 {
24     int s=0,fh=1;char ch=getchar();
25     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
26     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
27     return s*fh;
28 }
29 void dfs1(int u)
30 {
31     int i,v;
32     SIZE++;value[SIZE]=u;pos[u]=SIZE;
33     vis[u]=true;
35     {
36         v=edge[i].end;
37         if(vis[v]==false)
38         {
39             deep[v]=deep[u]+1;
40             P[v][0]=u;
41             dfs1(v);
42         }
43     }
44 }
45 void Ycl()
46 {
47     int i,j;
48     for(j=1;(1<<j)<=n;j++)
49     {
50         for(i=1;i<=n;i++)
51         {
52             if(P[i][j-1]!=-1)P[i][j]=P[P[i][j-1]][j-1];
53         }
54     }
55 }
56 int LCA(int x,int y)
57 {
58     int i,j;
59     if(deep[x]<deep[y])swap(x,y);
60     for(i=0;(1<<i)<=deep[x];i++);i--;
61     for(j=i;j>=0;j--)if(deep[x]-(1<<j)>=deep[y])x=P[x][j];
62     if(x==y)return x;
63     for(j=i;j>=0;j--)
64     {
65         if(P[x][j]!=-1&&P[x][j]!=P[y][j])
66         {
67             x=P[x][j];
68             y=P[y][j];
69         }
70     }
71     return P[x][0];
72 }
73 void Update(int x,int &y,int l,int r,int k)
74 {
75     y=++SIZE;
76     sum[y]=sum[x]+1;
77     if(l==r)return;
78     tree[y].left=tree[x].left;tree[y].right=tree[x].right;
79     int mid=(l+r)/2;
80     if(k<=mid)Update(tree[x].left,tree[y].left,l,mid,k);
81     else Update(tree[x].right,tree[y].right,mid+1,r,k);
82 }
83 int query(int l,int r,int A,int B,int C,int D,int k)
84 {
85     if(l==r)return l;
86     int mid=(l+r)/2,tmp=sum[tree[A].left]+sum[tree[B].left]-sum[tree[C].left]-sum[tree[D].left];
87     if(k<=tmp)return query(l,mid,tree[A].left,tree[B].left,tree[C].left,tree[D].left,k);
88     else return query(mid+1,r,tree[A].right,tree[B].right,tree[C].right,tree[D].right,k-tmp);
89 }
90 int Query(int A,int B,int k)
91 {
92     int C=LCA(A,B),D=P[C][0];
93     A=root[pos[A]];B=root[pos[B]];C=root[pos[C]];D=root[pos[D]];
94     return query(1,tot,A,B,C,D,k);
95 }
96 int main()
97 {
98     int m,i,bb,ee,k,k1,lastans,U,V,K;
101     sort(val+1,val+n+1);
102     tot=unique(val+1,val+n+1)-(val+1);
104     for(i=1;i<n;i++)
105     {
108     }
109     memset(P,-1,sizeof(P));SIZE=0;
110     memset(value,0,sizeof(value));//树上每个编号的实际的点.
111     memset(pos,0,sizeof(pos));//每个点在树上的编号.
112     dfs1(1);Ycl();
113     memset(root,0,sizeof(root));
114     SIZE=0;
115     for(i=1;i<=n;i++)//i为树上的节点.(即i为每个点在树上的编号.)
116     {
117         k=value[i];
118         k1=lower_bound(val+1,val+tot+1,a[k])-val;
119         Update(root[pos[P[k][0]]],root[i],1,tot,k1);
120     }
121     lastans=0;
122     for(i=1;i<=m;i++)
123     {
125         U^=lastans;
126         lastans=val[Query(U,V,K)];
127         printf("%d",lastans);
128         if(i!=m)printf("\n");
129     }
130     fclose(stdin);
131     fclose(stdout);
132     return 0;
133 }
View Code

posted @ 2016-03-14 19:51  微弱的世界  阅读(135)  评论(0编辑  收藏  举报