• [bzoj2120]数颜色


      TAT

      如果只维护画笔的颜色的话显然解决不了查询= =所以考虑维护别的东西。。

      令pre[i]表示第pre[i]支画笔颜色同笔i相同且离得最近(pre[i]<i)。对于区间[l,r]中,如果某一支笔x的pre值<l,那么这支笔的颜色是当前区间里第一个出现的,答案+1.

      然后我就脑残写了个线段树套treap。。。。。。

      外层线段树表示区间,内层按pre值建treap。查询的时候在线段树上拆成一个个区间,然后在treap里查询一下pre值比l小的笔的数目。

      因为修改时会改变pre值。。所以我再建了个treap'。。。。。。每种颜色一颗treap',treap'里以笔所在位置为关键字。

      所以每次修改某支画笔的颜色的时候,找出它原本的前驱后继改改改,再找出它颜色改变后的前驱后继改改改TAT。。

      其实就是维护一下前驱。。每次修改最多改变三支画笔的前驱(自己,原本的后继,颜色改变后的后继)。

      最后码了快5k。。。sxbk。。。其实正常做法不是分块暴力吗TAT

      本来做好被分块艹的准备了。。结果O(nlog²n)竟然战胜了O(n^1.5)。。。感人肺腑

      值得吐槽的是我已经连续若干次因为treap的更新写错而调了1h+了。。。。。。。。。。。

      另。。全部加inline后就从#6爬到#2了= =..inline大法好代码长度哭了

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int maxn=10023;
      7 struct zs{
      8     int num,id;
      9 }a[maxn<<1];
     10 struct ask{
     11     int l,r;bool id;
     12 }q[maxn];
     13 int i,j,n,m,cnt;
     14 int b[maxn],c[maxn<<1],pre[maxn],last[maxn<<1];
     15 int l[maxn*18],r[maxn*18],rnd[maxn*18],sz[maxn*18],w[maxn*18],num[maxn*18],tot;
     16 int rt[33233],size;
     17  
     18 int ra;char rx;
     19 inline int read(){
     20     rx=getchar(),ra=0;
     21     while(rx<'0'||rx>'9')rx=getchar();
     22     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     23 }
     24  
     25 inline void lturn(int &x,int R){
     26     r[x]=l[R],l[R]=x,sz[R]=sz[x],sz[x]=sz[l[x]]+w[x]+sz[r[x]],x=R;
     27 }
     28 inline void rturn(int &x,int L){
     29     l[x]=r[L],r[L]=x,sz[L]=sz[x],sz[x]=sz[l[x]]+w[x]+sz[r[x]],x=L;
     30 }
     31 inline void ins(int &x,int v){
     32     if(!x){x=++tot,rnd[x]=rand(),sz[x]=w[x]=1,num[x]=v;return;}
     33     ++sz[x];
     34     if(num[x]==v)w[x]++;else
     35     if(v<num[x]){
     36         ins(l[x],v);
     37         if(rnd[l[x]]<rnd[x])rturn(x,l[x]);
     38     }else{
     39         ins(r[x],v);
     40         if(rnd[r[x]]<rnd[x])lturn(x,r[x]);
     41     }
     42 }
     43 inline void del(int &x,int v){
     44     if(num[x]==v){
     45         if(w[x]>1)--w[x],--sz[x];else
     46         if(!(l[x]&&r[x]))x=l[x]|r[x];else
     47         if(rnd[l[x]]<rnd[r[x]])rturn(x,l[x]),del(x,v);
     48             else lturn(x,r[x]),del(x,v);
     49     }else if(v<num[x]) --sz[x],del(l[x],v);
     50     else --sz[x],del(r[x],v);
     51 }
     52 inline int get(int x,int v){
     53     if(!x)return 0;
     54     if(v<num[x])return get(l[x],v);else
     55     if(v==num[x])return sz[l[x]];else
     56     return get(r[x],v)+w[x]+sz[l[x]];
     57 }
     58 inline int query(int l,int r){
     59     if(l>r)swap(l,r);
     60     if(l==r)return 1;
     61     int l1=l;l+=size,r+=size;int sum=get(rt[l],l1)+get(rt[r],l1);
     62     for(;l^r^1;l>>=1,r>>=1){
     63         if(!(l&1))sum+=get(rt[l^1],l1);
     64         if(r&1)sum+=get(rt[r^1],l1);
     65     }
     66     return sum;
     67 }
     68 //---------------------------------------------------------------
     69  
     70 int Tl[maxn<<1],Tr[maxn<<1],Trnd[maxn<<1],Tnum[maxn<<1],Trt[maxn<<1],Ttot;
     71 int Tpre,Taft;
     72 inline void Tlturn(int &x,int R){
     73     Tr[x]=Tl[R],Tl[R]=x,x=R;
     74 }
     75 inline void Trturn(int &x,int L){
     76     Tl[x]=Tr[L],Tr[L]=x,x=L;
     77 }
     78 inline void Tins(int &x,int v){
     79     if(!x){x=++Ttot,Trnd[x]=rand(),Tnum[x]=v;return;}
     80     if(v<Tnum[x]){
     81         Tins(Tl[x],v);
     82         if(Trnd[Tl[x]]<Trnd[x])Trturn(x,Tl[x]);
     83     }else{
     84         Tins(Tr[x],v);
     85         if(Trnd[Tr[x]]<Trnd[x])Tlturn(x,Tr[x]);
     86     }
     87 }
     88 inline void Tdel(int &x,int v){
     89     if(Tnum[x]==v){
     90         if(!(Tl[x]&&Tr[x]))x=Tl[x]|Tr[x];else
     91         if(Trnd[Tl[x]]<Trnd[Tr[x]])Trturn(x,Tl[x]),Tdel(x,v);
     92             else Tlturn(x,Tr[x]),Tdel(x,v);
     93     }else if(v<Tnum[x]) Tdel(Tl[x],v);
     94     else Tdel(Tr[x],v);
     95 }
     96 inline void getpre(int x,int v){
     97     if(!x)return;
     98     if(Tnum[x]<v)Tpre=Tnum[x],getpre(Tr[x],v);else
     99     getpre(Tl[x],v);
    100 }
    101 inline void getaft(int x,int v){
    102     if(!x)return;
    103     if(Tnum[x]>v)Taft=Tnum[x],getaft(Tl[x],v);else
    104     getaft(Tr[x],v);
    105 }
    106  
    107 bool cmp(zs a,zs b){return a.num<b.num;}
    108 int main(){
    109     n=read(),m=read();char id;
    110     for(i=1;i<=n;i++)a[i].id=i,a[i].num=read();int n1=n;
    111     for(i=1;i<=m;i++){
    112         for(id=getchar();id<'A'||id>'Z';id=getchar());
    113         q[i].id=(id=='R');q[i].l=read(),q[i].r=read();
    114         if(q[i].id)a[++n1].id=i+n,a[n1].num=q[i].r;
    115     }
    116     sort(a+1,a+1+n1,cmp);cnt=0;
    117     for(i=1;i<=n1;i++){
    118         if(a[i].num!=a[i-1].num||i==1)c[++cnt]=a[i].num;
    119         if(a[i].id<=n)b[a[i].id]=cnt;else q[a[i].id-n].r=cnt;
    120     }
    121      
    122     for(size=1;size<n;size<<=1); size--;
    123     for(i=1;i<=n;i++){
    124         pre[i]=last[b[i]],last[b[i]]=i;
    125         for(j=i+size;j;j>>=1)ins(rt[j],pre[i]);
    126         Tins(Trt[b[i]],i);
    127     }
    128     for(i=1;i<=m;i++)
    129         if(!q[i].id)
    130             printf("%d
    ",query(q[i].l,q[i].r));
    131         else if(b[q[i].l]!=q[i].r){
    132             Tpre=0,getpre(Trt[b[q[i].l]],q[i].l),Taft=n+1,getaft(Trt[b[q[i].l]],q[i].l);
    133              
    134             if(Taft<=n){
    135                 for(j=Taft+size;j;j>>=1)del(rt[j],pre[Taft]),ins(rt[j],Tpre);
    136                 pre[Taft]=Tpre;
    137             }
    138                          
    139             Tpre=0,getpre(Trt[q[i].r],q[i].l),Taft=n+1,getaft(Trt[q[i].r],q[i].l);
    140             if(Taft<=n){
    141                 for(j=Taft+size;j;j>>=1)del(rt[j],pre[Taft]),ins(rt[j],q[i].l);
    142                 pre[Taft]=q[i].l;
    143             }
    144             for(j=q[i].l+size;j;j>>=1)del(rt[j],pre[q[i].l]),ins(rt[j],Tpre);
    145             pre[q[i].l]=Tpre,
    146              
    147             Tdel(Trt[b[q[i].l]],q[i].l),b[q[i].l]=q[i].r,Tins(Trt[b[q[i].l]],q[i].l);
    148         }
    149     return 0;
    150 }
    View Code
  • 相关阅读:
    PC 常用软件分享(无广告软件)
    PlyComputer2023多项式求值器2023 下载 Polynomial evaluation Solver 2023 download
    DymDim 1维碰撞运动学软件2023 下载 1D collision kinematics software 2023 download
    仙童公司的往事
    mqtt 协议理解
    rndis协议
    linux内存管理
    4G模块AT命令说明
    modbus rtu 字符间隔要求
    lua userdata 封装任意对象
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5134575.html
Copyright © 2020-2023  润新知