洛谷P4130 [NOI2007]项链工厂

正确做法应该是线段树呢
然而ODT开O2后可以卡着时间过
主要的trick就是旋转操作不用真的旋转,记一个tag就可以计算编号为i的珠子的实际位置了
就这样,好像没别的了....

#include<bits/stdc++.h>
using namespace std;
const int N=500005;
int n,m,c;
inline int read(){
    int s=0;char ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) s=s*10+ch-'0',ch=getchar();
    return s;
}
struct node{
    int l,r;mutable int v;
    node(){}
    node(int L,int R,int V){l=L,r=R,v=V;}
    inline bool operator < (const node & a) const {
        return l<a.l;
    }
};
set<node> s;
int mov,rev;
#define IT set<node>::iterator
inline IT split(int x){
    IT it=s.lower_bound(node(x,-1,0));
    if(it!=s.end()&&it->l==x) return it;
    --it;
    int l=it->l,r=it->r,v=it->v;
    s.erase(it);s.insert(node(l,x-1,v));
    return s.insert(node(x,r,v)).first;
}
inline void assign(int l,int r,int v){
    IT itr=split(r+1),itl=split(l);
    s.erase(itl,itr);s.insert(node(l,r,v));
}
inline int get_col(int x){
    IT it=s.lower_bound(node(x,-1,0));
    if(it!=s.end()&&it->l==x) return it->v;
    return (--it)->v;
}
inline int query(int l,int r){
    int ans=0,la=-1;
    IT itr=split(r+1),itl=split(l);
    for(; itl!=itr; ++itl){
        if(itl->v!=la) ans++;
        la=itl->v;
    }
    return ans;
}
inline int real_pos(int x){
    if(rev) x=n-x+2;x-=mov;
    x=x%n;if(x<1) x+=n;
    return x;
}
int main(){
    n=read(),c=read();
    int x,l,r;char op[10];
    for(int i=1;i<=n;i++) x=read(),s.insert(node(i,i,x));
    m=read();
    while(m--){
        scanf("%s",op);
        if(op[0]=='R') {
            x=read();mov+=rev?-x:x;
            mov=mov%n;if(mov<0) x+=n;
        }else if(op[0]=='F') rev^=1;
        else if(op[0]=='S'){
            l=read(),r=read();
            l=real_pos(l),r=real_pos(r);
            int a=get_col(l),b=get_col(r);
            assign(l,l,b);assign(r,r,a);
        }else if(op[0]=='P'){
            l=read(),r=read(),x=read();
            l=real_pos(l),r=real_pos(r);
            if(rev) swap(l,r);
            if(l<=r) assign(l,r,x);
            else assign(1,r,x),assign(l,n,x);
        }else if(op[1]=='S'){
            int ans;
            l=read(),r=read();
            l=real_pos(l),r=real_pos(r);
            if(rev) swap(l,r);
            if(l<=r) ans=query(l,r);
            else {
                ans=query(1,r)+query(l,n);
                if(ans>1) ans-=(get_col(1)==get_col(n));
            }
            printf("%d\n",ans);
        }else {
            int ans=query(1,n);
            printf("%d\n",ans>1?ans-(get_col(1)==get_col(n)):ans);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ustze/p/10347159.html