• [BZOJ3551][ONTAK2010]Peaks加强版


    题目大意:
      一个图上有$n(nle10^5)$个带权点,$m(mle5 imes10^5)$条带权边。有$q(qle5 imes10^5)$组询问,每次询问从点$v$出发,只经过权值小于等于$x$的边能到达的点中,权值第$k$大的点权。强制在线。

    思路:
      不强制在线时显然可以线段树合并。在线时需要建立Kruskal重构树,并对其DFS序建立主席树维护权值出现次数,每次询问结点权值小于等于$x$的虚点祖先所在的子树,求子树第$k$大值。

      1 #include<cstdio>
      2 #include<cctype>
      3 #include<cstring>
      4 #include<climits>
      5 #include<algorithm>
      6 #include<sys/mman.h>
      7 #include<sys/stat.h>
      8 class MMapInput {
      9     private:
     10         char *buf,*p;
     11         int size;
     12     public:
     13         MMapInput() {
     14             register int fd=fileno(stdin);
     15             struct stat sb;
     16             fstat(fd,&sb);
     17             size=sb.st_size;
     18             buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0));
     19             p=buf;
     20         }
     21         char getchar() {
     22             return (p==buf+size||*p==EOF)?EOF:*p++;
     23         }
     24 };
     25 MMapInput mmi;
     26 inline int getint() {
     27     register char ch;
     28     while(!isdigit(ch=mmi.getchar()));
     29     register int x=ch^'0';
     30     while(isdigit(ch=mmi.getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     31     return x;
     32 }
     33 const int N=1e5+1,N2=N<<1,logN=18,logN2=18,M=5e5,M2=N2;
     34 bool vis[N2];
     35 int n,m,q,tmp[N],h[N2],val[N2]={INT_MAX},dep[N2],anc[N2][logN2],in[N2],out[N2],cnt,tot,sz;
     36 struct Edge {
     37     int u,v,w;
     38     bool operator < (const Edge &another) const {
     39         return w<another.w;
     40     }
     41 };
     42 Edge e[M];
     43 struct DisjointSet {
     44     int anc[N2];
     45     DisjointSet() {
     46         for(register int i=0;i<N2;i++) anc[i]=i;
     47     }
     48     int find(const int &x) {
     49         return x==anc[x]?x:anc[x]=find(anc[x]);
     50     }
     51     void merge(const int &x,const int &y) {
     52         anc[find(x)]=find(y);
     53     }
     54     bool same(const int &x,const int &y) {
     55         return find(x)==find(y);
     56     }
     57 };
     58 DisjointSet s;
     59 struct Edge2 {
     60     int to,next;
     61 };
     62 Edge2 e2[M2];
     63 inline void add_edge(const int &u,const int &v) {
     64     e2[sz]=(Edge2){v,h[u]};h[u]=sz++;
     65 }
     66 inline void kruskal() {
     67     tot=n;
     68     std::sort(&e[0],&e[m]);
     69     for(register int i=0;i<m;i++) {
     70         const int u=e[i].u,v=e[i].v,w=e[i].w;
     71         if(!s.same(u,v)) {
     72             val[++tot]=w;
     73             add_edge(tot,s.find(u));
     74             add_edge(tot,s.find(v));
     75             s.merge(s.find(u),tot);
     76             s.merge(s.find(v),tot); 
     77         }
     78     }
     79 }
     80 inline int log2(const float &x) {
     81     return ((unsigned&)x>>23&255)-127;
     82 }
     83 class SegmentTree {
     84     private:
     85         struct Node {
     86             int val,left,right;
     87         };
     88         Node node[N*logN];
     89         int sz,new_node(const int &p) {
     90             node[++sz]=node[p];
     91             return sz;
     92         }
     93         void push_up(const int &p) {
     94             node[p].val=node[node[p].left].val+node[node[p].right].val;
     95         }
     96     public:
     97         int root[N2*2];
     98         void modify(int &p,const int &b,const int &e,const int &x) {
     99             p=new_node(p);
    100             if(b==e) {
    101                 node[p].val++;
    102                 return;
    103             }
    104             const int mid=(b+e)>>1;
    105             if(x<=mid) modify(node[p].left,b,mid,x);
    106             if(x>mid) modify(node[p].right,mid+1,e,x);
    107             push_up(p);
    108         }
    109         int query(const int &p,const int &q,const int &b,const int &e,const int &k) {
    110             if(node[q].val-node[p].val<k) return 0;
    111             if(b==e) return b;
    112             const int mid=(b+e)>>1;
    113             if(node[node[q].right].val-node[node[p].right].val>=k) {
    114                 return query(node[p].right,node[q].right,mid+1,e,k);
    115             } else {
    116                 return query(node[p].left,node[q].left,b,mid,k-(node[node[q].right].val-node[node[p].right].val));
    117             }
    118         }
    119 };
    120 SegmentTree t;
    121 void dfs(const int &x,const int &par) {
    122     vis[x]=true;
    123     dep[x]=dep[anc[x][0]=par]+1;
    124     for(register int i=1;i<=log2(dep[x]);i++) {
    125         anc[x][i]=anc[anc[x][i-1]][i-1];
    126     }
    127     in[x]=++cnt;
    128     t.root[in[x]]=t.root[in[x]-1];
    129     for(register int i=h[x];~i;i=e2[i].next) {
    130         const int &y=e2[i].to;
    131         dfs(y,x);
    132     }
    133     out[x]=++cnt;
    134     t.root[out[x]]=t.root[out[x]-1];
    135     if(x<=n) t.modify(t.root[out[x]],1,tmp[0],val[x]);
    136 }
    137 inline int find(int v,const int &x) {
    138     for(register int i=log2(dep[v]);~i;i--) {
    139         if(val[anc[v][i]]<=x) v=anc[v][i];
    140     }
    141     return v;
    142 }
    143 int main() {
    144     memset(h,-1,sizeof h);
    145     n=getint(),m=getint(),q=getint();
    146     for(register int i=1;i<=n;i++) {
    147         tmp[i]=val[i]=getint();
    148     }
    149     std::sort(&tmp[1],&tmp[n]+1);
    150     tmp[0]=std::unique(&tmp[1],&tmp[n]+1)-&tmp[1];
    151     for(register int i=1;i<=n;i++) {
    152         val[i]=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,val[i])-&tmp[0];
    153     }
    154     for(register int i=0;i<m;i++) {
    155         const int u=getint(),v=getint(),w=getint();
    156         e[i]=(Edge){u,v,w};
    157     }
    158     kruskal();
    159     for(register int i=1;i<=tot;i++) {
    160         if(!vis[i]) dfs(s.find(i),0);
    161     }
    162     for(register int i=0,ans=0;i<q;i++) {
    163         const int v=getint()^ans,x=getint()^ans,k=getint()^ans,p=find(v,x);
    164         ans=t.query(t.root[in[p]],t.root[out[p]],1,tmp[0],k);
    165         printf("%d
    ",ans?ans=tmp[ans]:-1); 
    166     }
    167     return 0;
    168 }
  • 相关阅读:
    2020全球C++及系统软件技术大会成功落下帷幕
    人工智能能力提升指导总结
    ABAP FUNCTION GUI_DOWN实际应用
    MySQL 数据库基础(二)(MySQL 服务基础与使用 MySQL 数据库)
    【推荐】开源项目ElasticAmbari助力 ElasticSearch、Kibana、ambari服务高效运维管理
    使用navicat连接oracle数据库遇到问题及解决方法
    cv::mat 保存sqlite数据库,使用qt
    工作总结:涉及数据库、软件测试等内容
    数据结构---归并排序
    C语言运算符优先级 详细列表
  • 原文地址:https://www.cnblogs.com/skylee03/p/8710634.html
Copyright © 2020-2023  润新知