• BZOJ4966 : 总统选举


    线段树维护每个点的最有可能是答案的数以及它的权重。

    合并两个节点的时候,将权重互相抵消,保留较大的那一个。

    得到答案后,再在对应权值的Treap中查询出现次数,检查是否真正是答案。

    时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<cstdlib>
    const int N=500010,M=1100010,BUF=30000000;
    int n,m,i,a[N],c,d,pos[N],v[M],f[M],V,F;char Buf[BUF],*buf=Buf;
    inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
    inline void merge(int a,int b,int c,int d,int&V,int&F){
      if(b==d){V=a+c,F=b;return;}
      if(!b||!d){V=a+c,F=b+d;return;}
      if(a==c){V=F=0;return;}
      if(a>c){V=a-c,F=b;return;}
      V=c-a,F=d;
    }
    void build(int x,int a,int b){
      if(a==b){
        v[x]=1;
        f[x]=::a[a];
        pos[a]=x;
        return;
      }
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b);
      merge(v[x<<1],f[x<<1],v[x<<1|1],f[x<<1|1],v[x],f[x]);
    }
    struct node{
      int val,cnt,sum,p;node*l,*r;
      node(){val=cnt=sum=p=0;l=r=NULL;}
      inline void up(){sum=cnt+l->sum+r->sum;}
    }*blank=new(node),pool[1500010],*cur=pool,*T[N];
    inline void Rotatel(node*&x){node*y=x->r;x->r=y->l;x->up();y->l=x;y->up();x=y;}
    inline void Rotater(node*&x){node*y=x->l;x->l=y->r;x->up();y->r=x;y->up();x=y;}
    void Insert(node*&x,int p){
      if(x==blank){
        x=cur++;x->val=p;x->l=x->r=blank;x->cnt=x->sum=1;x->p=rand();
        return;
      }
      x->sum++;
      if(p==x->val){x->cnt++;return;}
      if(p<x->val){
        Insert(x->l,p);
        if(x->l->p>x->p)Rotater(x);
      }else{
        Insert(x->r,p);
        if(x->r->p>x->p)Rotatel(x);
      }
    }
    void Delete(node*&x,int p){
      x->sum--;
      if(p==x->val){x->cnt--;return;}
      if(p<x->val)Delete(x->l,p);else Delete(x->r,p);
    }
    int Ask(node*&x,int p){
      if(x==blank)return 0;
      if(p==x->val)return x->r->sum;
      if(p<x->val)return x->cnt+x->r->sum+Ask(x->l,p);
      return Ask(x->r,p);
    }
    inline void change(int x){
      Delete(T[a[x]],x);
      Insert(T[a[x]=F],x);
      f[x=pos[x]]=F;
      for(x>>=1;x;x>>=1)merge(v[x<<1],f[x<<1],v[x<<1|1],f[x<<1|1],v[x],f[x]);
    }
    void ask(int x,int a,int b){
      if(c<=a&&b<=d){
        merge(V,F,v[x],f[x],V,F);
        return;
      }
      int mid=(a+b)>>1;
      if(c<=mid)ask(x<<1,a,mid);
      if(d>mid)ask(x<<1|1,mid+1,b);
    }
    inline bool check(int l,int r,int t){
      if(!t)return 0;
      int w=Ask(T[t],l-1)-Ask(T[t],r);
      return w*2>r-l+1;
    }
    int main(){
      fread(Buf,1,BUF,stdin);read(n),read(m);
      blank->l=blank->r=blank;
      for(i=1;i<=n;i++)T[i]=blank;
      for(i=1;i<=n;i++)read(a[i]),Insert(T[a[i]],i);
      build(1,1,n);
      while(m--){
        read(c),read(d);
        V=F=0;
        ask(1,1,n);
        if(!check(c,d,F))F=0;
        read(c);
        if(!F)F=c;
        read(c);
        while(c--)read(d),change(d);
        printf("%d
    ",F);
      }
      if(!check(1,n,f[1]))f[1]=-1;
      return printf("%d",f[1]),0;
    }
    

      

  • 相关阅读:
    新版本支付宝开发流程
    产生随机字串,可用来自动生成密码
    phpcmsv9的分页使用到的函数,直接拿来用就可以了
    js的一些函数
    JS一个简单的计时器
    linux 整理下常用命令
    mysql.sock
    第三方登录之QQ登录(二)——OAuth2.0处理流程介绍(以QQ登录为例)
    第三方登录之QQ登录(一)——QQ互联开放平台新建应用
    networkx AttributeError: 'DiGraph' object has no attribute 'edge'
  • 原文地址:https://www.cnblogs.com/clrs97/p/7337103.html
Copyright © 2020-2023  润新知