Bzoj3551 [ONTAK2010]Peaks加强版
Submit: 1622 Solved: 528
Description
【题目描述】同3545
Input
第一行三个数N,M,Q。
第二行N个数,第i个数为h_i
接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
接下来Q行,每行三个数v x k,表示一组询问。v=v xor lastans,x=x xor lastans,k=k xor lastans。如果lastans=-1则不变。
Output
同3545
Sample Input
Sample Output
HINT
【数据范围】同3545
Source
破题调一整晚,还不如重写一遍呢
图论 生成树 kruskal重构树
kruskal重构树是什么?没见过的(黑)科技啊
在用kruskal建生成树时,不连接原来的边,而是新建一个结点,向要连接的两点连边,边权为原边权。
这样建出的生成树,具有自叶子向根上溯,经过边权单调不减的特性。
有张直观的示意图见:http://www.cnblogs.com/GXZlegend/p/6293547.html
利用这个性质,可以倍增上溯找到当前点经过权值不超过x的边能到达的最远祖先,该祖先点的子树(里的有效点)就是能到达的所有点。
在这些点里面找第k大的即可。具体可以用dfs序+主席树维护。
各种蠢错误不提,遇到了两个坑点:
1、询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰
↑discuss里说不包括点v本身,如果从点v出发哪儿也去不了,应该输出-1。但是正确性不明,看网上题解,有的代码判了这个,有的没判,对拍时候会出错,但是似乎都可以A
2、异或以后会出现询问v超过范围的情况,算无解。
↑然而popoQQQ学长和黄学长的代码好像压根儿没管这个啊QAQ,出界情况蜜汁自然溢出不影响结果,然而我一样的写法就数组溢出无限RE。
↑数据好像卡了v出界的情况,又规避了v在n~cnt(生成树新建的结点范围)内的询问,经测试v>n判无解和v>cnt判无解都可以过。
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const int mxn=101010; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 struct edge{ 17 int v,nxt,w; 18 }e[mxn<<2]; 19 int hd[mxn*2],mct=0; 20 void add_edge(int u,int v,int w){ 21 e[++mct].v=v;e[mct].w=w;e[mct].nxt=hd[u];hd[u]=mct;return; 22 } 23 struct Edge{ 24 int x,y,w; 25 bool operator < (Edge b)const{return w<b.w;} 26 }eg[mxn*5]; 27 // 28 int dfn[mxn*2],out[mxn*2],dtime=0; 29 bool vis[mxn*2]; 30 int dis[mxn*2],dep[mxn*2],f[mxn*2][20]; 31 int mp[mxn*2]; 32 void DFS(int u,int fa){ 33 vis[u]=1; 34 dfn[u]=++dtime; 35 mp[dtime]=u; 36 dep[u]=dep[fa]+1; 37 for(int i=1;i<19;i++) f[u][i]=f[f[u][i-1]][i-1]; 38 for(int i=hd[u],v;i;i=e[i].nxt){ 39 v=e[i].v; 40 f[v][0]=u; 41 dis[u]=max(dis[u],e[i].w);//要到达当前点需要经过的权值最大边 42 DFS(v,u); 43 } 44 out[u]=dtime; 45 return; 46 } 47 int FTP(int u,int x){ 48 for(int i=18;i>=0;i--){ 49 if(dis[f[u][i]]<=x)u=f[u][i]; 50 } 51 return u; 52 } 53 // 54 struct node{ 55 int l,r; 56 int sz; 57 }t[mxn*50]; 58 int rt[mxn*3],root,cnt=0; 59 void update(int p,int v,int l,int r,int y,int &rt){ 60 rt=++cnt; 61 // printf("update:%d %d l:%d r:%d y:%d rt:%d\n",p,v,l,r,y,rt); 62 t[rt]=t[y]; 63 t[rt].sz++; 64 if(l==r)return; 65 int mid=(l+r)>>1; 66 if(p<=mid)update(p,v,l,mid,t[y].l,t[rt].l); 67 else update(p,v,mid+1,r,t[y].r,t[rt].r); 68 return; 69 } 70 int query(int k,int l,int r,int y,int rt){ 71 // printf("rt:%d y:%d sz:%d %d\n",rt,y,t[rt].sz,t[y].sz); 72 // printf("l:%d r:%d\n",l,r); 73 if(t[rt].sz-t[y].sz<k)return -1;//无解 74 if(l==r)return l; 75 int mid=(l+r)>>1; 76 if(t[t[rt].r].sz-t[t[y].r].sz>=k)return query(k,mid+1,r,t[y].r,t[rt].r); 77 else return query(k-t[t[rt].r].sz+t[t[y].r].sz,l,mid,t[y].l,t[rt].l); 78 } 79 // 80 int n,m,Q,h[mxn],n_cnt=0; 81 int bas[mxn],id[mxn]; 82 int lastans=0; 83 // 84 int fa[mxn*3]; 85 int find(int x){ 86 return fa[x]==x?x:fa[x]=find(fa[x]); 87 } 88 void kruskal(){ 89 sort(eg+1,eg+m+1); 90 int i,j; 91 for(i=1;i<=n;i++)fa[i]=i; 92 n_cnt=n; 93 for(i=1;i<=m;i++){ 94 int x=eg[i].x,y=eg[i].y; 95 int u=find(x),v=find(y); 96 if(u==v)continue; 97 n_cnt++; 98 fa[n_cnt]=n_cnt; 99 add_edge(n_cnt,u,eg[i].w); 100 add_edge(n_cnt,v,eg[i].w); 101 fa[u]=n_cnt;fa[v]=n_cnt;//要更新的是u,v 102 root=n_cnt;//update root 103 if(n_cnt==2*n-1)break; 104 } 105 return; 106 } 107 // 108 void solve(){ 109 for(int i=1;i<=n_cnt;i++){ 110 if(mp[i]<=n){ 111 update(id[mp[i]],1,1,n,rt[i-1],rt[i]); 112 } 113 else rt[i]=rt[i-1]; 114 } 115 // 116 int v,x,k; 117 for(int i=1;i<=Q;i++){ 118 v=read();x=read();k=read(); 119 if(lastans!=-1){//XOR 120 v^=lastans; x^=lastans; k^=lastans; 121 } 122 if(v>n_cnt || !v){ 123 lastans=-1; 124 printf("-1\n"); 125 continue; 126 } 127 v=FTP(v,x); 128 int pos=query(k,1,n,rt[dfn[v]],rt[out[v]]); 129 if(pos!=-1)pos=bas[pos]; 130 lastans=pos; 131 printf("%d\n",pos); 132 } 133 return; 134 } 135 int main(){ 136 // freopen("Input.in","r",stdin); 137 int i,j; 138 n=read();m=read();Q=read(); 139 for(i=1;i<=n;i++){ 140 h[i]=read(); 141 bas[i]=h[i]; 142 } 143 sort(bas+1,bas+n+1); 144 int ed=unique(bas+1,bas+n+1)-bas-1; 145 for(i=1;i<=n;i++){ 146 id[i]=lower_bound(bas+1,bas+ed+1,h[i])-bas; 147 } 148 for(i=1;i<=m;i++){ 149 eg[i].x=read();eg[i].y=read();eg[i].w=read(); 150 } 151 kruskal(); 152 dis[0]=0x3f3f3f3f;//init 153 for(i=1;i<=n_cnt;i++)if(!vis[i]){ 154 int x=find(i); 155 DFS(x,0); 156 } 157 solve(); 158 return 0; 159 } 160
本文为博主原创文章,转载请注明出处。