• Treap


     

    Graph and Queries

     UVALive - 5031 

    第一道Treap,对着白书敲的=_=||

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 //15:15--16:00
      4 struct Node{
      5     Node *ch[2]; //左右子树
      6     int r;   //随机优先级
      7     int v;   //
      8     int s;  //节点总数
      9     Node(int v):v(v){ch[0]=ch[1]=NULL;r=rand();s=1; }
     10     bool operator <(const Node &a)const {
     11         return r<a.r;
     12     }
     13     int cmp(int x)const {
     14         if(x==v) return -1;
     15         return x<v ? 0:1;
     16     }
     17 
     18     void maintain(){
     19         s=1;
     20         if(ch[0]!=NULL) s+=ch[0]->s;
     21         if(ch[1]!=NULL) s+=ch[1]->s;
     22     }
     23 };
     24 
     25 void rotate(Node* &o,int d){   //0左旋,1右旋
     26     Node *k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
     27     o->maintain();k->maintain();o=k;
     28 }
     29 
     30 void insert(Node* &o,int x){
     31     if(o==NULL) o=new Node(x);
     32     else {
     33         int d=(x<o->v?0:1);  //不用cmp函数,因为可能有相同节点
     34         insert(o->ch[d],x);
     35         if(o->ch[d]->r>o->r) rotate(o,d^1);
     36     }
     37     o->maintain();
     38 }
     39 
     40 void remove(Node* &o,int x){
     41     int d=o->cmp(x);
     42     if(d==-1){
     43         Node* u=o;
     44         if(o->ch[0]!=NULL&&o->ch[1]!=NULL){
     45             int d2=(o->ch[0]->r>o->ch[1]->r?1:0);
     46             rotate(o,d2);remove(o->ch[d2],x);
     47         }else {
     48             if(o->ch[0]==NULL) o=o->ch[1];else o=o->ch[0];
     49             delete u;  //
     50         }
     51     }else
     52         remove(o->ch[d],x);
     53     if(o!=NULL) o->maintain();
     54 }
     55 
     56 const int maxc=500000+10;
     57 
     58 struct Command
     59 {
     60     char type;
     61     int x,p;  //根据type,p代表k或者v
     62 }command[maxc];
     63 
     64 const int maxn=20000+10;
     65 const int maxm=60000+10;
     66 
     67 int n,m,weight[maxn],from[maxm],to[maxm],removed[maxm];
     68 
     69 //并查集
     70 int pa[maxn];
     71 int gf(int x){
     72     return x==pa[x]?x:pa[x]=gf(pa[x]);
     73 }
     74 
     75 //名次树
     76 Node* root[maxn];  //Treap
     77 int kth(Node* o,int k){
     78     if(o==NULL||k<=0||k>o->s) return 0;
     79     int s=(o->ch[1]==NULL?0:o->ch[1]->s);
     80     if(k==s+1) return o->v;
     81     else if(k<=s) return kth(o->ch[1],k);
     82     else return kth(o->ch[0],k-s-1);
     83 }
     84 
     85 void mergeto(Node* &a,Node* &b){
     86     if(a->ch[0]!=NULL) mergeto(a->ch[0],b);
     87     if(a->ch[1]!=NULL) mergeto(a->ch[1],b);
     88     insert(b,a->v);
     89     delete a;
     90     a=NULL;
     91 }
     92 
     93 void removetree(Node* &x){
     94     if(x->ch[0]!=NULL)  removetree(x->ch[0]);
     95     if(x->ch[1]!=NULL)  removetree(x->ch[1]);
     96     delete x;
     97     x=NULL;
     98 }
     99 //主程序相关
    100 void add_edge(int x){
    101     int u=gf(from[x]),v=gf(to[x]);
    102     if(u!=v){
    103         if(root[u]->s<root[v]->s){
    104             pa[u]=v;
    105             mergeto(root[u],root[v]);
    106         }else {
    107             pa[v]=u;
    108             mergeto(root[v],root[u]);
    109         }
    110     }
    111 }
    112 
    113 int query_cnt;
    114 long long query_tot;
    115 void query(int x,int k){
    116     query_cnt++;
    117     query_tot+=kth(root[gf(x)],k);
    118 }
    119 
    120 void change_weight(int x,int v){
    121     int u=gf(x);
    122     remove(root[u],weight[x]);
    123     insert(root[u],v);
    124     weight[x]=v;
    125 }
    126 
    127 int main(){
    128     int kase=0;
    129     while(scanf("%d%d",&n,&m)==2&&n){
    130         for(int i=1;i<=n;i++) scanf("%d",&weight[i]);
    131         for(int i=1;i<=m;i++) scanf("%d%d",&from[i],&to[i]);
    132         memset(removed,0,sizeof(removed));
    133 
    134         //读命令
    135         int c=0;
    136         for(;;){
    137             char type;
    138             int x,p=0,v=0;
    139             scanf(" %c",&type);
    140             if(type=='E') break;
    141             scanf("%d",&x);
    142             if(type=='D') removed[x]=1;
    143             if(type=='Q') scanf("%d",&p);
    144             if(type=='C'){
    145                 scanf("%d",&v);
    146                 p=weight[x];
    147                 weight[x]=v;
    148             }
    149             command[c++]=(Command){type,x,p};
    150         }
    151 
    152         //最终的图
    153         for(int i=1;i<=n;i++){
    154             pa[i]=i;
    155             if(root[i]!=NULL) removetree(root[i]);
    156             root[i]=new Node(weight[i]);
    157         }
    158 
    159         for(int i=1;i<=m;i++) if(!removed[i]) add_edge(i);
    160 
    161         //反向操作
    162         query_tot=query_cnt=0;
    163         for(int i=c-1;i>=0;i--){
    164             if(command[i].type=='D') add_edge(command[i].x);
    165             if(command[i].type=='Q') query(command[i].x,command[i].p);
    166             if(command[i].type=='C') change_weight(command[i].x,command[i].p);
    167         }
    168         printf("Case %d: %.6lf
    ",++kase,query_tot/(double)query_cnt);
    169     }
    170     return 0;
    171 }
    View Code
  • 相关阅读:
    前端常用插件收藏文章
    vue+ts修改父组件属性的写法。
    JS new date在IOS出现的问题
    js 和各种屏幕高度的写法
    react 配置ant时遇见的一个Error: Multiple configuration files found. Please remove one: – package.json#babel – .babelrc 解决方案
    vue 的sync用法
    VUE Right-hand side of ‘instanceof’ is not an object 解决方案
    记录一下navicat的快捷键
    什么是servlet(转)
    Java位运算在程序设计中的使用:位掩码(BitMask)
  • 原文地址:https://www.cnblogs.com/yijiull/p/7259444.html
Copyright © 2020-2023  润新知