zoukankan      html  css  js  c++  java
  • Bzoj3545 [ONTAK2010]Peaks

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2038  Solved: 535

    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。

    Source

    Kruskal  启发式合并 树 treap 脑洞题

    将询问离线,按询问x值从小到大排序,回答每个询问前将x值小于询问值的边加进集合,进行启发式合并。

    用treap维护集合内的结点,进行排名查询以回答询问。

    要回答的是目标山的高度,不是编号←样例真是充满了误导性

    算法比较好想,然而并不会写treap的启发式合并……

    各种开脑洞,发现要么太难实现,要么实现了不能保证二叉树性质WAWAWA

    依稀记得听说过可持久化treap的合并是以某个权值为界把treap拆分开,再合并成一整棵新树,想想就好难写。

    最后放弃了挣扎,选择了暴力把一棵treap上的点全建到另一棵treap上。

    然而一对拍又挂了,检查了好久好久,发现合并时候少传了一个地址。

    于是一下午+半个晚上就水过去了。

    随机数种子很好用,并没有特殊的意义(认真脸)

      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=120010;
     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 x,y,w;
     18     bool operator < (edge b)const{return w<b.w;}
     19 }e[mxn*5];
     20 struct QUE{
     21     int v,x,k,id;
     22     bool operator < (QUE b)const{return x<b.x;}
     23 }q[mxn*5];
     24 //
     25 int fa[mxn],sz[mxn];
     26 int find(int x){
     27     return fa[x]==x?x:fa[x]=find(fa[x]);
     28 }
     29 //
     30 struct node{
     31     int l,r;
     32     int v,sz,cnt;
     33     int rand;
     34 }t[mxn*5];
     35 int rot[mxn],cnt;
     36 void pushup(int x){
     37     t[x].sz=t[t[x].l].sz+t[t[x].r].sz+t[x].cnt;
     38 }
     39 void Rt(int &k){
     40     int now=t[k].l;
     41     t[k].l=t[now].r;
     42     t[now].r=k;
     43     pushup(k);pushup(now);
     44     k=now;
     45     return;
     46 }
     47 void Lt(int &k){
     48     int now=t[k].r;
     49     t[k].r=t[now].l;
     50     t[now].l=k;
     51     pushup(k);pushup(now);
     52     k=now;
     53     return;
     54 }
     55 void DEBUG(){
     56     printf("Debug
    ");
     57     for(int j=0;j<=cnt;j++){
     58         printf("#%d: lc:%d rc:%d sz:%d cnt:%d
    ",j,t[j].l,t[j].r,t[j].sz,t[j].cnt);
     59     }
     60     printf("fin
    ");
     61     return;
     62 }
     63 int bin[mxn*2],top=0;
     64 void insert(int v,int c,int &rt){
     65     if(!rt){
     66         if(top)rt=bin[top--];
     67         else rt=++cnt;
     68         t[rt].cnt=t[rt].sz=c;
     69         t[rt].v=v;
     70         t[rt].rand=rand();
     71         t[rt].l=t[rt].r=0;
     72         return;
     73     }
     74     t[rt].sz+=c;
     75     if(t[rt].v==v) t[rt].cnt+=c;
     76     else if(v<t[rt].v){
     77         insert(v,c,t[rt].l);
     78         if(t[t[rt].l].rand>t[rt].rand){
     79             Rt(rt);
     80         }
     81     }
     82     else{
     83         insert(v,c,t[rt].r);
     84         if(t[t[rt].r].rand>t[rt].rand){
     85             Lt(rt);
     86         }
     87     }
     88     return;
     89 }
     90 void Merge(int &x,int &y){//y也会被改变,需要传地址 
     91     if(!x)return;
     92     Merge(t[x].l,y);
     93     Merge(t[x].r,y);
     94     int tmp=x;
     95     x=0;
     96     insert(t[tmp].v,t[tmp].cnt,y);
     97     bin[++top]=tmp;
     98     return;
     99 }
    100 int ask_rank(int rt,int k){
    101     if(!rt)return 0;
    102     if(t[t[rt].r].sz>=k)return ask_rank(t[rt].r,k);
    103     else if(t[t[rt].r].sz+t[rt].cnt>=k)return t[rt].v;
    104     else return ask_rank(t[rt].l,k-t[t[rt].r].sz-t[rt].cnt);
    105 }
    106 void link(int u,int v){
    107     u=find(u);v=find(v);
    108     if(u==v)return;
    109     if(t[u].sz<t[v].sz)swap(u,v);
    110     Merge(rot[v],rot[u]);//v向u合并 
    111     fa[v]=u;
    112     return;
    113 }
    114 int n,m,Q;
    115 int h[mxn],ans[mxn*5];
    116 
    117 void solve(){
    118     int i,j;
    119     srand(19260817);
    120     for(i=1;i<=n;i++){
    121         insert(h[i],1,rot[i]);
    122     }//treap init 
    123     int hd=1;
    124     for(i=1;i<=Q;i++){
    125         while(e[hd].w<=q[i].x && hd<=m){
    126             link(e[hd].x,e[hd].y);
    127             hd++;
    128         }
    129         int x=find(q[i].v);
    130         int res=ask_rank(rot[x],q[i].k);
    131         if(!res)ans[q[i].id]=-1;
    132         else ans[q[i].id]=res;
    133     }
    134     return;
    135 }
    136 int main(){
    137 //    freopen("Input.in","r",stdin);
    138     int i,j;
    139     n=read();m=read();Q=read();
    140     for(i=1;i<=n;i++){
    141         h[i]=read();
    142         fa[i]=i;
    143     }
    144     for(i=1;i<=m;i++){
    145         e[i].x=read();e[i].y=read();e[i].w=read();
    146     }
    147     for(i=1;i<=Q;i++){
    148         q[i].v=read();q[i].x=read();q[i].k=read();q[i].id=i;
    149     }
    150     sort(e+1,e+m+1);
    151     sort(q+1,q+Q+1);
    152     solve();
    153     for(i=1;i<=Q;i++){
    154         printf("%d
    ",ans[i]);
    155     }
    156     return 0;
    157 }
  • 相关阅读:
    Elementary Methods in Number Theory Exercise 1.2.25
    Elementary Methods in Number Theory Exercise 1.2.14
    图解欧几里德算法
    图解欧几里德算法
    Elementary Methods in Number Theory Exercise 1.2.14
    Android中的长度单位详解(dp、sp、px、in、pt、mm)
    分享下多年积累的对JAVA程序员成长之路的总结
    android异常之都是deamon惹的祸The connection to adb is down, and a severe error has occured.
    TomatoCartv1.1.8.2部署时报错
    JavaScript浏览器对象之二Document对象
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6657352.html
Copyright © 2011-2022 走看看