主席树+dfs SPOJ BZOJ2588 Count on a tree

这道题我由于智障错误导致一直错。

在树上建主席树,加上lca思想,很简单。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=200005;
 4 struct node
 5 {
 6     int to,nex;
 7 }e[N<<1];
 8 struct tree
 9 {
10     int l,r,s;
11 }t[2000005];
12 int n,m,cnt,cn,mx,pre,head[N],f[N][21],a[N],rt[N],d[N];
13 vector<int>v;
14 inline int get(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
15 void add(int x,int y)
16 {
17     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;
18 }
19 void update(int &x,int l,int r,int p,int num)
20 {
21     x=++cn;t[x]=t[p];t[x].s++;int mid=l+r>>1;
22     if(l==r)return ;
23     if(mid>=num)update(t[x].l,l,mid,t[p].l,num);
24     else update(t[x].r,mid+1,r,t[p].r,num);
25 }
26 void dfs(int x,int fa)
27 {
28     update(rt[x],1,mx,rt[fa],get(a[x]));f[x][0]=fa;d[x]=d[fa]+1;
29     for(int i=1;i<=20;++i)
30     if(d[x]>=(1<<i))
31     f[x][i]=f[f[x][i-1]][i-1];
32     for(int i=head[x];i;i=e[i].nex)
33     {
34         int y=e[i].to;
35         if(y==fa)continue;
36         dfs(y,x);
37     }
38 }
39 int lca(int x,int y)
40 {
41     if(d[x]<d[y])swap(x,y);
42     int tmp=d[x]-d[y];
43     for(int i=20;i>=0;i--)
44     if(tmp&(1<<i))x=f[x][i];
45     for(int i=20;i>=0;i--)
46     {
47         if(f[x][i]!=f[y][i])
48             x=f[x][i],y=f[y][i];
49     }
50     return x==y?x:f[x][0];
51 }
52 int query(int l,int r,int rt1,int rt2,int rt3,int rt4,int k)
53 {
54     if(l==r){
55         pre=v[l-1];return l;
56     }
57     int sum=t[t[rt1].l].s+t[t[rt2].l].s-t[t[rt3].l].s-t[t[rt4].l].s;
58     int mid=(l+r)>>1;
59     if(sum>=k)return query(l,mid,t[rt1].l,t[rt2].l,t[rt3].l,t[rt4].l,k);
60     else return query(mid+1,r,t[rt1].r,t[rt2].r,t[rt3].r,t[rt4].r,k-sum);
61 }
62 int main()
63 {
64     //freopen("rand.out","r",stdin);
65     //freopen("my.out","w",stdout);
66     int x,y,k;
67     scanf("%d%d",&n,&m);
68     for(int i=1;i<=n;++i)
69     {
70         scanf("%d",&a[i]);v.push_back(a[i]);
71     }
72     sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());mx=v.size();
73     for(int i=1;i<n;++i)
74     {
75         scanf("%d%d",&x,&y);
76         add(x,y);add(y,x);
77     }
78     dfs(1,0);
79     for(int i=1;i<=m;++i)
80     {
81         scanf("%d%d%d",&x,&y,&k);
82         int z=lca(pre^x,y);
83         printf("%d",v[query(1,mx,rt[pre^x],rt[y],rt[z],rt[f[z][0]],k)-1]);
84         if(i<m) puts("");
85     }
86     return 0;
87 }

BZOJ最后换行会PE。。。。

posted @ 2017-12-09 21:36  大奕哥&VANE  阅读(123)  评论(0编辑  收藏  举报