cf1076g
虽然是个 *3000 的题,但感觉也不是很 nb 的亚子嗷(
首先发现这字里行间都写着 ICG 三个大字,感觉很舒服。
可能的状态只有可能是这样的:某个后缀原封不动,然后这个后缀的上一个位置 ,好家伙这幌子打得漂亮。
那考虑暴力算法:就从右往左对
很自然的想到,维护一个最近
再想想就发现 wsbl。这个状态数这么少,只有 (早就预料到是这个复杂度)。
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int n,m,qu;
bool a[N];
struct trans{
int to[6];
int &operator[](int x){return to[x];}
trans(){for(int i=0;i<6;i++)to[i]=i;}
friend trans operator*(trans x,trans y){
trans z;
for(int i=0;i<6;i++)z[i]=x[y[i]];
return z;
}
};
struct segtree{
struct node{trans t,t0;bool lz;}nd[N<<2];
#define t(p) nd[p].t
#define t0(p) nd[p].t0
#define lz(p) nd[p].lz
void sprup(int p){
t(p)=t(p<<1)*t(p<<1|1);
t0(p)=t0(p<<1)*t0(p<<1|1);
}
void bld(int l=1,int r=n,int p=1){
lz(p)=0;
if(l==r){
trans &t=t(p),&t0=t0(p);
for(int i=1;i<m;i++)t[i]=t0[i]=i+1;t[m]=t0[m]=0;
t[0]=0,t0[0]=1;
if(a[l])swap(t,t0);
return;
}
int mid=l+r>>1;
bld(l,mid,p<<1),bld(mid+1,r,p<<1|1);
sprup(p);
}
void init(){
bld();
}
void sprdwn(int p){
if(lz(p)){
swap(t(p<<1),t0(p<<1)),lz(p<<1)^=1;
swap(t(p<<1|1),t0(p<<1|1)),lz(p<<1|1)^=1;
lz(p)=0;
}
}
void flip(int l,int r,int p=1,int tl=1,int tr=n){
if(l<=tl&&r>=tr)return swap(t(p),t0(p)),lz(p)^=1,void();
sprdwn(p);
int mid=tl+tr>>1;
if(l<=mid)flip(l,r,p<<1,tl,mid);
if(r>mid)flip(l,r,p<<1|1,mid+1,tr);
sprup(p);
}
trans ask(int l,int r,int p=1,int tl=1,int tr=n){
if(l<=tl&&r>=tr)return t(p);
sprdwn(p);
int mid=tl+tr>>1;trans res;
if(l<=mid)res=res*ask(l,r,p<<1,tl,mid);
if(r>mid)res=res*ask(l,r,p<<1|1,mid+1,tr);
return res;
}
}segt;
int main(){
cin>>n>>m>>qu;
for(int i=1;i<=n;i++){
long long x;
scanf("%lld",&x);
a[i]=x&1;
}
segt.init();
while(qu--){
int tp,l,r;
scanf("%d%d%d",&tp,&l,&r);
if(tp==1){
long long x;
scanf("%lld",&x);
if(!(x&1))continue;
segt.flip(l,r);
}
else printf("%d\n",segt.ask(l,r)[0]==1?2:1);
}
return 0;
}