[NOIP2018模拟赛10.23]发呆报告

闲扯

考场看了眼题目感觉很难,一个小时敲完了所有暴力...嗯然后就在那里发呆什么事也没做

T3考场上把数据结构想了个遍都不会完成1操作,现在看这种思路其实之前也接触过...

比较玄学的一件事情就是T1一开始测得有40分结果过了会看爆0了,难不成被续走了(然而后面测了一下真的爆0了)

太菜了不讲了

T1 sequence

gu

T2 bomb

gu

T3 queue

考虑使用分块在线处理,我们发现瓶颈是1操作,我们将在\([l,r]\)上的这个操作看成将r放到l位之前,然后所有都往后一位

于是我们可以将每一块设立两个指针指向块的左右端点,对于同一块内的操作暴力处理

对于\(l,r\)在不同块上的情况,一种naiive的做法是直接将\(r\)位的元素插入到\(l\)之前,但是这样可能会使块的大小不平衡,需要分裂重构比较麻烦

但是有个方法能避免这个问题

\(l\)所在块为p,\(r\)所在块为q,我们把\(p\)\(q-1\)中的每一块的末尾元素放到下一块的开头,这样的话就保持平衡了

我们可以将每一块设成一个\(deque\)(双端队列)来简洁地完成上述操作

/*
  code by RyeCatcher
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <utility>
#include <queue>
#include <vector>
#include <cmath>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <iostream>
#define DEBUG freopen("dat.in","r",stdin);freopen("wa.out","w",stdout);
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define ri register int
#define ll long long
#define ull unsigned long long
#define SIZE 1<<22
using std::min;
using std::max;
using std::deque;
using std::pair;
using namespace __gnu_pbds;
inline char gc(){
    static char buf[SIZE],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
}
//#define gc getchar
template <class T>inline void read(T &x){
    x=0;int ne=0;char c;
    while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;
    while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
}
const int maxn=100005;
const int maxb=355;
const int inf=0x7fffffff;
int n,m,size,k,a[maxn];
int L[maxn],R[maxn],pos[maxn];
deque <int> blo[maxb];
int cnt[maxn][maxb],sz[maxn];
int main(){
    int x,y,l,r;
    FO(queue);
    freopen("queue2.in","r",stdin);
    freopen("queue2.ans","w",stdout);
    //DEBUG
    //freopen("dat.in","r",stdin);
    read(n),read(m);
    if(!(n+m)){
        return 0;
    }
    size=sqrt(n+0.5);
    for(ri i=1;i<=size;i++)L[i]=(i-1)*size+1,R[i]=i*size;
    if(R[size]<n)R[++size]=n,L[size]=R[size-1]+1;
    for(ri i=1;i<=n;i++){
        read(a[i]);
    }
    for(ri i=1;i<=size;i++){
        for(ri j=L[i];j<=R[i];j++){
            pos[j]=i;
            sz[i]++;
            cnt[a[j]][i]++;
            blo[i].push_back(a[j]);
        }
    }
    int opt,p,q;
    deque<int>::iterator it;
    while(m--){
        read(opt),read(l),read(r);
        p=pos[l],q=pos[r];
        if(opt==1){
            if(p==q){
                x= *(blo[p].begin()+r-L[p]);
                blo[p].erase(blo[p].begin()+r-L[p]);
                blo[p].insert(blo[p].begin()+l-L[p],x);
            }
            else{
                x= *(blo[q].begin()+r-L[q]);
                //printf("--%d %d--\n",q,x);
                blo[q].erase(blo[q].begin()+r-L[q]);
                sz[q]--,cnt[x][q]--;
                for(ri i=p;i<q;i++){
                    y= blo[i].back();
                    blo[i].pop_back();
                    cnt[y][i]--,sz[i]--,
                    blo[i+1].push_front(y);
                    cnt[y][i+1]++,sz[i+1]++;
                }
                blo[p].insert(blo[p].begin()+l-L[p],x);
                sz[p]++,cnt[x][p]++;
            }
        }
        if(opt==2){
            read(k);
            if(p==q){
                x=0;
                for(it=blo[p].begin()+l-L[p];it<=blo[p].begin()+r-L[p];it++){
                    if(*it==k)x++;
                }
                printf("%d\n",x);
            }
            else{
                x=0;
                for(it =blo[p].begin()+l-L[p];it!=blo[p].end();it++){
                    if(*it==k)x++;
                    //printf("%d ",*it);
                }
                for(it =blo[q].begin();it<=blo[q].begin()+r-L[q];it++){
                    if(*it==k)x++;
                    //printf("%d ",*it);
                }
                for(ri i=p+1;i<q;i++)x+=cnt[k][i];
                printf("%d\n",x);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Rye-Catcher/p/9839086.html