bzoj 3551: [ONTAK2010]Peaks加强版

  这道题用到了Kruskal重构树,有个性质是这棵树是一个大根堆,而且每个点所能延伸出去的联通块在树的dfs序中是连续的一段,所以就可以用主席树维护了。

  

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define N 200005
  6 #define M 500005
  7 #define ls a[x].l,a[y].l,l,mid
  8 #define rs a[x].r,a[y].r,mid+1,r
  9 using namespace std;
 10 int n,m,q;
 11 int v[N];
 12 struct node
 13 {
 14     int x,y,z;
 15     friend bool operator < (node aa,node bb)
 16     {
 17         return aa.z<bb.z;
 18     }
 19 }b[M];
 20 int f[N+M];
 21 int find(int x)
 22 {
 23     if(x==f[x])return x;
 24     return f[x]=find(f[x]);
 25 }
 26 int head[M],ver[M],nxt[M],tot;
 27 void add(int aa,int bb)
 28 {
 29     tot++;nxt[tot]=head[aa];head[aa]=tot;ver[tot]=bb;return ;
 30 }
 31 bool vis[M];
 32 int st[N],ed[N],z;
 33 int fa[N][18],mx[N][18];
 34 int d[N],jian[N];
 35 void dfs(int x,int ff)
 36 {
 37     vis[x]=1;st[x]=z+1;
 38     if(!head[x])
 39     {
 40         z++;jian[z]=v[x];
 41     }
 42     for(int i=head[x];i;i=nxt[i])
 43     {
 44         if(ver[i]==ff)continue;
 45         fa[ver[i]][0]=x;
 46         mx[ver[i]][0]=max(d[ver[i]],d[x]);
 47         dfs(ver[i],x);
 48     }
 49     ed[x]=z;
 50 }
 51 int num;
 52 void yu()
 53 {
 54     for(int i=1;i<=17;i++)
 55     {
 56         for(int j=1;j<=num;j++)
 57         {
 58             fa[j][i]=fa[fa[j][i-1]][i-1];
 59             mx[j][i]=max(mx[j][i-1],mx[fa[j][i-1]][i-1]);
 60         }
 61     }return ;
 62 }
 63 int root[N];
 64 struct ndode
 65 {
 66     int l,r,sum;
 67 }a[4000005];int cnt;
 68 void merge(int x,int y,int l,int r,int pos,int z)
 69 {
 70     if(l==r)
 71     {
 72         a[x].sum=a[y].sum+z;
 73         return ;
 74     }
 75     int mid=(l+r)>>1;
 76     if(pos<=mid)
 77     {
 78         a[x].l=++cnt;
 79         a[x].r=a[y].r;
 80         merge(ls,pos,z);
 81     }
 82     else
 83     {
 84         a[x].r=++cnt;
 85         a[x].l=a[y].l;
 86         merge(rs,pos,z);
 87     }
 88     a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
 89 }
 90 int qur(int x,int y,int l,int r,int k)
 91 {
 92     if(l==r)return l;
 93     if(a[x].sum-a[y].sum<k)return -1;
 94     int ss=a[a[x].r].sum-a[a[y].r].sum;
 95     int mid=(l+r)>>1;
 96     if(ss>=k)return qur(rs,k);
 97     else return qur(ls,k-ss);
 98 }
 99 int li[N];int cr;
100 int main()
101 {
102     scanf("%d%d%d",&n,&m,&q);
103     for(int i=1;i<=n;i++)
104     {
105         scanf("%d",&v[i]);
106         li[i]=v[i];
107         d[i]=0;
108     }cr=n;
109     sort(li+1,li+cr+1);
110     cr=unique(li+1,li+cr+1)-li-1;
111     for(int i=1;i<=n;i++)
112     {
113         v[i]=lower_bound(li+1,li+cr+1,v[i])-li;
114     }
115     for(int i=1;i<=m;i++)
116     {
117         scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].z);
118     }
119     sort(b+1,b+m+1);
120     for(int i=1;i<=n+m;i++)f[i]=i;
121     num=n;
122     for(int i=1;i<=m;i++)
123     {
124         int aa=find(b[i].x),bb=find(b[i].y);
125         if(aa!=bb)
126         {
127             num++;
128             d[num]=b[i].z;
129             f[aa]=num;f[bb]=num;
130             add(num,aa);add(num,bb);
131         }
132     }
133     for(int i=1;i<=n;i++)
134     {
135         if(!vis[i])
136         {
137             int tt=find(i);
138             fa[tt][0]=tt;mx[tt][0]=d[tt];
139             dfs(tt,-1);
140         }
141     }
142     yu();
143     for(int i=1;i<=n;i++)
144     {
145         root[i]=++cnt;
146         merge(root[i],root[i-1],1,cr,jian[i],1);
147     }
148     int las=-1;
149     int t1,t2,t3;
150     for(int i=1;i<=q;i++)
151     {
152         scanf("%d%d%d",&t1,&t2,&t3);
153         if(las!=-1)
154         {
155             t1^=las;t2^=las;t3^=las;
156         }
157         int now=t1;
158         for(int j=17;j>=0;j--)
159         {
160             if(mx[now][j]<=t2)now=fa[now][j];
161         }
162         las=qur(root[ed[now]],root[st[now]-1],1,cr,t3);
163         if(las!=-1)las=li[las];
164         printf("%d\n",las);
165     }
166     return 0;
167 }
View Code

 

posted @ 2017-02-15 11:19  SD_le  阅读(174)  评论(0编辑  收藏  举报
重置按钮