zoukankan      html  css  js  c++  java
  • bzoj3545/bzoj3551 [ONTAK2010]Peaks/Peaks加强版

    bzoj3545/bzoj3551 [ONTAK2010]Peaks/Peaks加强版

    传送门:bzoj  bzoj

    wdnmd为什么加强版不是权限题原题却是啊

    3545: [ONTAK2010]Peaks

    Time Limit: 10 Sec  Memory Limit: 128 MB
    [Submit][Status][Discuss]

    Description

     

    在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

    Input

     

    第一行三个数N,M,Q。
    第二行N个数,第i个数为h_i
    接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
    接下来Q行,每行三个数v x k,表示一组询问。

    Output

     

    对于每组询问,输出一个整数表示答案。

    Sample Input

     

    10 11 4
    1 2 3 4 5 6 7 8 9 10
    1 4 4
    2 5 3
    9 8 2
    7 8 10
    7 1 4
    6 7 1
    6 4 8
    2 1 5
    10 8 10
    3 4 7
    3 4 6
    1 5 2
    1 5 6
    1 5 8
    8 9 2

    Sample Output

     

    6
    1
    -1
    8

    HINT

     

    【数据范围】

    N<=10^5, M,Q<=5*10^5,h_i,c,x<=10^9。


    果然还是太年轻了居然被这种水平的题吊打。。。

    简短思路:

    首先来一次kruskal

    很明显不在树上的边都用不上

    然后这时候就出现了kruskal重构树

    随便挂个讲得好的博客

    拼出来重构树之后用线段树合并或是主席树都行

    以下通用代码(只差一排注释)

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 using namespace std;
      5 const int N=200011,inf=0x7f7f7f7f,M=500011;
      6 template<typename TP>inline void read(TP &kk)
      7 {
      8     TP ret=0,f=1;char ch=getchar();
      9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     10     while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
     11     kk=ret*f;
     12 }
     13 int n,m,Q;
     14 struct shino
     15 {
     16     int x,y,w;
     17     bool operator < (const shino &a)const
     18     {return w<a.w;}
     19 }sl[M];
     20 int snr;
     21 #define lson(x) (son[x][0])
     22 #define rson(x) (son[x][1])
     23 struct sgt
     24 {
     25     int c[N*36],son[N*36][2],cnt;
     26     void ins(const int x,int &px,int pl,int pr)
     27     {
     28         if(!px) px=++cnt;
     29         c[px]++;
     30         if(pl==pr) return;
     31         int mi=pl+pr>>1;
     32         if(x<=mi) ins(x,lson(px),pl,mi);
     33         else ins(x,rson(px),mi+1,pr);
     34     }
     35     int merge(const int px,const int py)
     36     {
     37         if(!px||!py) return px+py;
     38         int pz=++cnt;
     39         c[pz]=c[px]+c[py];
     40         lson(pz)=merge(lson(px),lson(py));
     41         rson(pz)=merge(rson(px),rson(py));
     42         return pz;
     43     }
     44     int query(int k,const int px,int pl,int pr)
     45     {
     46         if(pl==pr) return pl;
     47         int mi=pl+pr>>1;
     48         if(k<=c[lson(px)]) return query(k,lson(px),pl,mi);
     49         else return query(k-c[lson(px)],rson(px),mi+1,pr);
     50     }
     51 }tr;
     52 int rt[N];
     53 int h[N];
     54 int f[N],fa[N][20],val[N],son[N][2];
     55 int find(int x)
     56 {
     57     if(f[x]!=f[f[x]]) return f[x]=find(f[x]);
     58     return f[x];
     59 }
     60 void kksk()//k,k(ru)sk(al)... 无端玩梗的rkk是屑
     61 {
     62     snr=n,val[0]=inf;
     63     for(int i=1;i<=m;i++)
     64     {
     65         int x=find(sl[i].x),y=find(sl[i].y);
     66         if(x==y) continue;
     67         f[x]=f[y]=fa[x][0]=fa[y][0]=++snr;
     68         val[snr]=sl[i].w;
     69         son[snr][0]=x,son[snr][1]=y;
     70     }
     71 }
     72 
     73 int saki[N];
     74 int main()
     75 {
     76     read(n),read(m),read(Q);
     77     for(int i=1;i<=n;i++)
     78         read(sl[i].w),sl[i].x=i;
     79     sort(sl+1,sl+1+n);
     80     for(int i=1;i<=n;i++)
     81     {
     82         if(sl[i].w!=sl[i-1].w) saki[++snr]=sl[i].w;
     83         h[sl[i].x]=snr;
     84     }
     85     for(int i=1;i<=m;i++)
     86         read(sl[i].x),read(sl[i].y),read(sl[i].w);
     87     sort(sl+1,sl+1+m);
     88     for(int i=1;i<=n*2;i++) f[i]=i;
     89     kksk();
     90     for(int i=1;i<=19;i++)
     91         for(int x=1;x<=snr;x++)
     92             fa[x][i]=fa[fa[x][i-1]][i-1];
     93     for(int i=1;i<=n;i++) tr.ins(h[i],rt[i],1,n);
     94     for(int i=n+1;i<=n*2;i++) rt[i]=tr.merge(rt[lson(i)],rt[rson(i)]);
     95     int lans=0,xi,vi,ki;
     96     while(Q--)
     97     {
     98         read(xi),read(vi),read(ki);
     99         xi^=lans,vi^=lans,ki^=lans;//前后就差个这行
    100         for(int i=19;i>=0;i--)
    101         {
    102             if(val[fa[xi][i]]<=vi) xi=fa[xi][i];
    103         }
    104         if(tr.c[rt[xi]]<ki){puts("-1");lans=0;}
    105         else printf("%d
    ",lans=saki[tr.query(tr.c[rt[xi]]-ki+1,rt[xi],1,n)]);
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    2804 最大最小数质因数
    5429 多重背包
    1851 越狱
    Gvim使用
    3622 假期
    4906 删数问题
    2845 排序的代价
    poj 3352
    常用正则表达式汇总
    功能简单例子
  • 原文地址:https://www.cnblogs.com/rikurika/p/11332801.html
Copyright © 2011-2022 走看看