首先数字最多只有 30 种,很容易想到状压,用一个 int 来表示一个区间数字出现的状态。
很容易想到用线段树来维护一个区间数字出现的状态。
#include"cstdio"#include"cctype"#include"algorithm"using namespace std;#define lc o*2#define rc o*2+1#define mid (l+r)/2int read(){ int c,x=0; while(!isdigit(c=getchar())); while(x=x*10+c-'0',isdigit(c=getchar())); return x;}int f[400001],c[400001];void update(int o){ if(c[o]) f[o]=(1<R || r =L && r<=R) { c[o]=v; update(o); return; } push(o); change(lc,l,mid,L,R,v); change(rc,mid+1,r,L,R,v); update(o);}int query(int o,int l,int r,int L,int R){ if(l>R || r =L && r<=R) return f[o]; push(o); return query(lc,l,mid,L,R)|query(rc,mid+1,r,L,R);}int calc(int k){ int res=0; for(;k;k>>=1) if(k&1) res++; return res;}int main(){ c[1]=f[1]=1; int L=read(),T=read(),O=read(); while(O--) { char c; while(c=getchar(),c!='P' && c!='C'); if(c=='C') { int A=read(),B=read(),C=read(); if(A>B) swap(A,B); change(1,1,L,A,B,C); } else { int A=read(),B=read(); if(A>B) swap(A,B); printf("%d\n",calc(query(1,1,L,A,B))); } } return 0;}