zoukankan      html  css  js  c++  java
  • 【bzoj3545】[ONTAK2010]Peaks 线段树合并

    【bzoj3545】[ONTAK2010]Peaks

    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。

    题解

      离散后排序,维护加边顺序,然后就是线段树合并了,权值线段树。

      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstdio>
      6 
      7 #define N 100007
      8 #define M 500007
      9 #define ll long long
     10 using namespace std;
     11 inline int read()
     12 {
     13     int x=0,f=1;char ch=getchar();
     14     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     15     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 
     19 int n,m,q,sz;
     20 int fa[N],rt[N],ans[M],disc[N],h[N];
     21 int siz[M*10],ls[M*10],rs[M*10];
     22 struct Node
     23 {
     24     int x,y,difficulty;
     25 }a[M];
     26 struct Date
     27 {
     28     int x,limit,k,id;
     29 }b[M];
     30 
     31 int find(int num)
     32 {
     33     if (fa[num]!=num) fa[num]=find(fa[num]);
     34     return fa[num];
     35 }
     36 bool cmp(Node x,Node y)
     37 {
     38     return x.difficulty<y.difficulty;
     39 }
     40 bool cmp1(Date x,Date y)
     41 {
     42     return x.limit<y.limit;
     43 }
     44 
     45 int merge(int x,int y)
     46 {
     47     if (!x)return y;
     48     if (!y)return x;
     49     if (!ls[x]&&!rs[x])
     50     {
     51         siz[x]=siz[x]+siz[y];
     52         return x;
     53     }
     54     ls[x]=merge(ls[x],ls[y]);
     55     rs[x]=merge(rs[x],rs[y]);
     56     siz[x]=siz[ls[x]]+siz[rs[x]];
     57     return x;
     58 }
     59 void ins(int &p,int l,int r,int z)
     60 {
     61     if (!p)p=++sz,siz[p]=1;
     62     if (l==r) return;
     63     int mid=(l+r)>>1;
     64     if (z<=mid)ins(ls[p],l,mid,z);
     65     else ins(rs[p],mid+1,r,z);
     66 }
     67 int query(int p,int l,int r,int rank)
     68 {
     69     if (l==r) return l;
     70     int mid=(l+r)>>1;
     71     if (rank<=siz[ls[p]])return query(ls[p],l,mid,rank);
     72     else return query(rs[p],mid+1,r,rank-siz[ls[p]]);
     73 }
     74 void solve()
     75 {
     76     int now=0;
     77     for (int i=1;i<=q;i++)
     78     {
     79         while(now<m&&a[now+1].difficulty<=b[i].limit)
     80         {
     81             int x=find(a[now+1].x),y=find(a[now+1].y);
     82             if (x!=y)
     83             {
     84                 fa[y]=x;
     85                 rt[x]=merge(rt[x],rt[y]);
     86             }
     87             now++;
     88         }
     89         int x=find(b[i].x);
     90         if (siz[rt[x]]<b[i].k) ans[b[i].id]=-1;
     91         else ans[b[i].id]=disc[query(rt[x],1,n,siz[rt[x]]-b[i].k+1)];
     92     }
     93     for (int i=1;i<=q;i++)
     94         printf("%d
    ",ans[i]);
     95 }
     96 int main()
     97 {
     98     freopen("fzy.in","r",stdin);
     99     freopen("fzy.out","w",stdout);
    100     
    101     n=read(),m=read(),q=read();
    102     for (int i=1;i<=n;i++)
    103         disc[i]=h[i]=read(),fa[i]=i;
    104     sort(disc+1,disc+n+1);
    105     for (int i=1;i<=n;i++)
    106         h[i]=lower_bound(disc+1,disc+n+1,h[i])-disc;
    107     for (int i=1;i<=n;i++)
    108         ins(rt[i],1,n,h[i]);
    109     
    110     for (int i=1;i<=m;i++)
    111         a[i].x=read(),a[i].y=read(),a[i].difficulty=read();
    112     sort(a+1,a+m+1,cmp);
    113     for (int i=1;i<=q;i++)
    114         b[i].x=read(),b[i].limit=read(),b[i].k=read(),b[i].id=i;
    115     sort(b+1,b+q+1,cmp1);
    116     solve();
    117 }
  • 相关阅读:
    普通文件的上传(表单上传和ajax文件异步上传)
    React Ant Design+Node.js Express+Mysql实现后端分页(带富文本编辑器)
    Express中增删改查相关的中间件
    React中使用富文本编辑器react-draft-wysiwyg
    Express中aixos请求的(批量)删除用POST方法,其它请求的(批量)删除可以用DELETE方法
    React中将字符串转义成html语句
    Vue中如何设置代理跨域请求数据
    React中如何设置代理跨域请求数据
    axios发送post请求,服务端无法正常获取参数(比如:node服务器无法通过req.body获取参数)解决方案
    LeetCode-162.寻找峰值
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8142979.html
Copyright © 2011-2022 走看看