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

    题目大意:
      一个图上有$n(nleq100000)$个带权点,$m(mleq500000)$条带权边。有$q(qleq500000)$组询问,每次询问从点$v$出发,只经过权值小于等于$x$的边能到达的点中,权值第$k$大的点权。

    思路:
      离线处理每个询问。将询问和边分别按权值排序,处理到当前询问时,将权值小于等于$x$的边加入到图中。用权值线段树维护每个连通块的权值。点的联通情况用并查集维护(相当于Kruskal),权值线段树直接合并。时间复杂度$O(nlog n+mlog m+qlog q+qlog n)$。

      1 #include<cstdio>
      2 #include<cctype>
      3 #include<algorithm>
      4 inline int getint() {
      5     register char ch;
      6     while(!isdigit(ch=getchar()));
      7     register int x=ch^'0';
      8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
      9     return x;
     10 }
     11 const int N=100001,M=500000,Q=500000;
     12 int h[N],tmp[N],ans[Q];
     13 struct Edge {
     14     int u,v,w;
     15     bool operator < (const Edge &another) const {
     16         return w<another.w;
     17     }
     18 };
     19 Edge e[M];
     20 struct Query {
     21     int v,x,k,id;
     22     bool operator < (const Query &another) const {
     23         return x<another.x;
     24     }
     25 };
     26 Query q[Q];
     27 struct DisjointSet {
     28     int anc[N];
     29     int find(const int &x) {
     30         return x==anc[x]?x:anc[x]=find(anc[x]);
     31     }
     32     void reset(const int &n) {
     33         for(register int i=1;i<=n;i++) anc[i]=i;
     34     }
     35     void merge(const int &x,const int &y) {
     36         anc[find(y)]=find(x);
     37     }
     38     bool same(const int &x,const int &y) {
     39         return find(x)==find(y);
     40     }
     41 };
     42 DisjointSet s;
     43 class SegmentTree {
     44     private:
     45         struct Node {
     46             int val;
     47             Node *left,*right;
     48             Node(const int &v):val(v),left(NULL),right(NULL) {}
     49         };
     50         void modify(Node *&p,const int &b,const int &e,const int &x) {
     51             p=new Node(1);
     52             if(b==e) return;
     53             const int mid=(b+e)>>1;
     54             if(x<=mid) modify(p->left,b,mid,x);
     55             if(x>mid) modify(p->right,mid+1,e,x);
     56         }
     57     public:
     58         Node *root[N];
     59         void reset(const int &n) {
     60             for(register int i=1;i<=n;i++) {
     61                 modify(root[i],1,tmp[0],h[i]);
     62             }
     63         }
     64         void merge(Node *&p1,Node *const &p2) {
     65             if(!p1) {
     66                 p1=p2;
     67                 return;
     68             }
     69             if(!p2) return;
     70             p1->val+=p2->val;
     71             merge(p1->left,p2->left);
     72             merge(p1->right,p2->right);
     73             delete p2;
     74         }
     75         int query(const Node *const &p,const int &b,const int &e,const int &k) const {
     76             if(p->val<k) return -1;
     77             if(b==e) return b;
     78             const int mid=(b+e)>>1;
     79             if(!p->right) return query(p->left,b,mid,k);
     80             if(k<=p->right->val) return query(p->right,mid+1,e,k);
     81             return query(p->left,b,mid,k-p->right->val);
     82         }
     83 };
     84 SegmentTree t;
     85 inline void add_edge(const Edge &e) {
     86     if(s.same(e.u,e.v)) return;
     87     t.merge(t.root[s.find(e.u)],t.root[s.find(e.v)]);
     88     s.merge(e.u,e.v);
     89 }
     90 int main() {
     91     const int n=getint(),m=getint(),cnt_q=getint();
     92     for(register int i=1;i<=n;i++) {
     93         tmp[i]=h[i]=getint();
     94     }
     95     std::sort(&tmp[1],&tmp[n]+1);
     96     tmp[0]=std::unique(&tmp[1],&tmp[n]+1)-&tmp[1];
     97     for(register int i=1;i<=n;i++) {
     98         h[i]=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,h[i])-&tmp[0];
     99     }
    100     for(register int i=0;i<m;i++) {
    101         const int u=getint(),v=getint(),w=getint();
    102         e[i]=(Edge){u,v,w};
    103     }
    104     std::sort(&e[0],&e[m]);
    105     for(register int i=0;i<cnt_q;i++) {
    106         const int v=getint(),x=getint(),k=getint();
    107         q[i]=(Query){v,x,k,i};
    108     }
    109     std::sort(&q[0],&q[cnt_q]);
    110     s.reset(n);
    111     t.reset(n);
    112     for(register int i=0,p=0;i<cnt_q;i++) {
    113         while(p<m&&e[p].w<=q[i].x) add_edge(e[p++]);
    114         ans[q[i].id]=t.query(t.root[s.find(q[i].v)],1,tmp[0],q[i].k);
    115     }
    116     for(register int i=0;i<cnt_q;i++) {
    117         printf("%d
    ",~ans[i]?tmp[ans[i]]:-1);
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    Id_Name
    注入类型(Injection Type)
    搭建 Spring 2.5.6 开发环境
    模拟Spring框架
    AJAX 学习笔记 2017_05_04
    Gson 转换hibernate级联对象出现StackOverFlow(堆栈溢出)问题
    页面左侧可收缩菜单案例
    struts1.3.10 和 hibernate 3.3.2 一起加载时 出现javax.servlet.ServletException: java.lang.NoSuchMethodError: antlr.collections.A 错误
    1.21 Java基础总结 数组知识
    1.20 Java基础总结 输入数据类型判断 Java低耦合原则 for嵌套思路
  • 原文地址:https://www.cnblogs.com/skylee03/p/8460875.html
Copyright © 2011-2022 走看看