zoukankan      html  css  js  c++  java
  • Bzoj3551 [ONTAK2010]Peaks加强版

    Time Limit: 20 Sec  Memory Limit: 128 MB
    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
    ",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
    ",rt,y,t[rt].sz,t[y].sz);
     72 //  printf("l:%d r:%d
    ",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
    ");
    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
    ",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 
  • 相关阅读:
    Github挂载大文件解决方案
    UWP 更强大的文件获取能力
    UWP 打开系统设置面板
    Windows 10
    Flutter
    Android笔记(三):View一些值得注意的地方
    Android笔记(二):savedIndstanceState 和 Bundle
    Android笔记(一):this 的表示范围和 Context
    用atom写LaTeX文档
    博客园LaTeX数学公式功能及效果展示
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6661564.html
Copyright © 2011-2022 走看看