• [HNOI2012]永无乡


    思路:
    对于每一个点,建立一棵权值线段树,然后用并查集维护图的连通性,同时合并线段树维护每个连通块的权值。
    由于一些奇怪的原因,这道题代码从头到尾总共打了3遍。
    交到洛谷上发现是MLE,原因是数组开小了。
    然后交到别的OJ上,发现在BZOJ是RE,在CodeVS上是TLE。
    然后加了读优两边都AC了。

      1 #include<cstdio>
      2 #include<cctype>
      3 inline int getint() {
      4     char ch;
      5     while(!isdigit(ch=getchar()));
      6     int x=ch^'0';
      7     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
      8     return x;
      9 }
     10 const int N=100001,logN=18;
     11 class DisjointSet {
     12     private:
     13         int anc[N];
     14     public:
     15         DisjointSet() {
     16             for(int i=0;i<N;i++) anc[i]=i;
     17         }
     18         int Find(const int x) {
     19             return x==anc[x]?x:anc[x]=Find(anc[x]);
     20         }
     21         void Union(const int x,const int y) {
     22             anc[Find(x)]=Find(y);
     23         }
     24         bool isConnected (const int x,const int y) {
     25             return Find(x)==Find(y);
     26         }
     27 };
     28 DisjointSet s;
     29 class SegmentTree {
     30     private:
     31         static const int nil=0;
     32         int val[N*logN],left[N*logN],right[N*logN];
     33         int sz;
     34         int newnode() {
     35             return ++sz;
     36         }
     37         void push_up(const int p) {
     38             val[p]=val[left[p]]+val[right[p]];
     39         }
     40     public:
     41         SegmentTree() {
     42             val[nil]=0;
     43             sz=0;
     44         }
     45         int id[N],root[N];
     46         void insert(int &p,const int b,const int e,const int x) {
     47             p=newnode();
     48             if(b==e) {
     49                 left[p]=right[p]=nil;
     50                 val[p]=1;
     51                 return;
     52             }
     53             int mid=(b+e)>>1;
     54             left[p]=right[p]=nil;
     55             if(x<=mid) insert(left[p],b,mid,x);
     56             if(x>mid) insert(right[p],mid+1,e,x);
     57             push_up(p);
     58         }
     59         int merge(int p1,int p2) {
     60             if(!p1||!p2) return p1|p2;
     61             val[p1]+=val[p2];
     62             left[p1]=merge(left[p1],left[p2]);
     63             right[p1]=merge(right[p1],right[p2]);
     64             return p1;
     65         }
     66         int query(const int p,const int b,const int e,const int k) {
     67             if(val[p]<k) return -1;
     68             if(b==e) return id[b];
     69             int mid=(b+e)>>1;
     70             if(val[left[p]]>=k) {
     71                 return query(left[p],b,mid,k);
     72             }
     73             else {
     74                 return query(right[p],mid+1,e,k-val[left[p]]);
     75             }
     76         }
     77 };
     78 SegmentTree t;
     79 int main() {
     80     int n=getint(),m=getint();
     81     for(int i=1;i<=n;i++) {
     82         int x=getint();
     83         t.insert(t.root[i],1,n,x);
     84         t.id[x]=i;
     85     }
     86     while(m--) {
     87         int u=getint(),v=getint();
     88         if(s.isConnected(u,v)) continue;
     89         t.root[s.Find(v)]=t.merge(t.root[s.Find(v)],t.root[s.Find(u)]);
     90         s.Union(u,v);
     91     }
     92     for(int q=getint();q;q--) {
     93         char op[2];
     94         scanf("%s",op);
     95         if(op[0]=='Q') {
     96             int x=getint(),k=getint();
     97             printf("%d
    ",t.query(t.root[s.Find(x)],1,n,k));
     98         }
     99         if(op[0]=='B') {
    100             int u=getint(),v=getint();
    101             if(s.isConnected(u,v)) continue;
    102             t.root[s.Find(v)]=t.merge(t.root[s.Find(v)],t.root[s.Find(u)]);
    103             s.Union(u,v);
    104         }
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    【推广】+发送短信
    【Linux】+文件操作
    【CRT】+文件上传与下载
    【Java】+查看调用关系
    【博客园】+设置
    【Java】+http
    【Postman】
    【Java】+模拟浏览器操作
    【Java】+快速打印数组
    【Java】+字符串
  • 原文地址:https://www.cnblogs.com/skylee03/p/7445278.html
Copyright © 2020-2023  润新知