【题解】P3939数颜色

【题解】P3939 数颜色

不要数据结构和模板学傻了...

考虑到兔子们交换都是相邻的,说明任何一次交换只会引起\(O(1)\)的变化。

我们开很多\(vector\)存没种兔子的下标就好了。到时候二分查找查询。

复杂度\(O(nlogn)\)

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<bitset>
#include<vector>
#include<map>
#include<ctime>
#include<cstdlib>
#include<set>
#include<bitset>
#include<stack>
#include<list>
#include<cmath>
using namespace std;
#define RP(t,a,b) for(register int (t)=(a),edd_=(b);t<=edd_;++t)
#define DRP(t,a,b) for(register int (t)=(a),edd_=(b);t>=edd_;--t)
#define ERP(t,a) for(int t=head[a];t;t=e[t].nx)
#define Max(a,b) ((a)<(b)?(b):(a))
#define Min(a,b) ((a)<(b)?(a):(b))
#define TMP template<class ccf>
typedef long long ll;
TMP inline ccf qr(ccf k){
    char c=getchar();
    ccf x=0;
    int q=1;
    while(c<48||c>57)
    q=c==45?-1:q,c=getchar();
    while(c>=48&&c<=57)
    x=x*10+c-48,c=getchar();
    if(q==-1)
    x=-x;
    return x;
}
const int maxn=3e5+15;
int data[maxn];
vector < int > col[maxn];
int n,m;
inline int div(vector < int >& p,int lb,int rb,int k){
    // to lb
    int mid;
    int ret=0;
    do{
    mid=(lb+rb)>>1;
    if(p[mid]>=k)
        rb=mid-1,ret=mid;
    else
        lb=mid+1;
    }while(lb<=rb);
    return ret;
}

inline int div2(vector < int > &p,int lb,int rb,int k){
    int ret=-1;
    int mid;
    do{
    mid=(lb+rb)>>1;
    if(p[mid]<=k)
        lb=mid+1,ret=mid;
    else
        rb=mid-1;
    }while(lb<=rb);
    return ret;
}


inline void upd(int c,int pos,int to){
    int ret=div(col[c],0,col[c].size()-1,pos);
    if(ret<0)
    return void(cout<<"err!\n");
    col[c][ret]=to;
}

inline int cnt(int c,int lb,int rb){
    int ret=0;
    int siz=col[c].size()-1;
    if(siz<0)
    return 0;
    if(rb<col[c][0])
    return 0;
    if(lb>col[c][siz])
    return 0;
    ret+=div2(col[c],0,siz,rb);
    ret-=div(col[c],0,siz,lb);
    return ret+1;
}

int t1,t2,t3,t4;
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    n=qr(1);
    m=qr(1);
    RP(t,1,n){
    data[t]=qr(1);
    col[data[t]].push_back(t);
    }
    RP(t,1,m){
    t1=qr(1);
    if(t1==1){
        t2=qr(1);
        t3=qr(1);
        t4=qr(1);
        cout<<cnt(t4,t2,t3)<<endl;
    }else{
        t2=qr(1);
        if(data[t2]==data[t2+1])
        continue;
        else{
        upd(data[t2],t2,t2+1);
        upd(data[t2+1],t2+1,t2);
        swap(data[t2],data[t2+1]);
        }
    }
    }
    return 0;
}

posted @ 2019-01-29 11:43  谁是鸽王  阅读(232)  评论(0编辑  收藏  举报