P1558 色板游戏
>>>
然后发现颜色范围好像只有30;
所以,我就想到一种sao操作,搞30颗线段树。
每颗线段树代表一种颜色。
那么对于题中的两种操作:
1.修改。我们for循环扫一遍所有颜色,把其他颜色的线段树l->r修改成0,要修改的颜色所对应的线段树改成1。
2.询问。也是for循环,如果l->r这个区间的第k种颜色所对应的线段树有值,则ans++。
时间复杂度也很低,大概是(MLlog(L)*T).
>>>线段树 只是 线性结构 query/change/areaAdd/areaMull 都是在add mul sum 处理
而 pushdown 则是对 add mul sum 进行下放处理
::: res->0
:::build(1,1,1,l) 初始状态只有 1 号颜色
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------debug\n"); using namespace std; const int maxn=1e5+10; int sum[33][maxn<<2],cln[33][maxn<<2]; int l,t,o; void build(int tp,int k,int l,int r) { if(l==r) { sum[tp][k]=1; return; } int mid=l+r>>1; build(tp,k<<1,l,mid); build(tp,k<<1|1,mid+1,r); sum[tp][k]=sum[tp][k<<1]+sum[tp][k<<1|1]; } void pushdown(int tp,int k) { if(cln[tp][k]==0) return; if(cln[tp][k]==-1){ sum[tp][k<<1]=sum[tp][k<<1|1]=0; cln[tp][k<<1]=cln[tp][k<<1|1]=-1; } else{ sum[tp][k<<1]=sum[tp][k<<1|1]=1; cln[tp][k<<1]=cln[tp][k<<1|1]=1; } cln[tp][k]=0; } void change(int tp,int k,int l,int r,int x,int y,int val)//cln -> 标记 { if(l>y||r<x) return;// sum -> 区间和的标记 if(x<=l&&r<=y) { if(val==0) sum[tp][k]=0,cln[tp][k]=-1; else sum[tp][k]=cln[tp][k]=1; return; } pushdown(tp,k); int mid=l+r>>1; if(x<=mid) change(tp,k<<1,l,mid,x,y,val);//会一直处理下去,直到 sum的 全更新 if(mid<=y) change(tp,k<<1|1,mid+1,r,x,y,val); sum[tp][k]=sum[tp][k<<1]+sum[tp][k<<1|1]; } int query(int tp,int k,int l,int r,int x,int y) { if(l>y||r<x) return 0; if(x<=l&&r<=y) return sum[tp][k]; pushdown(tp,k); int mid=l+r>>1,res=0;//res -> 0 or 栈存储 无限 存贮 if(x<=mid) res+=query(tp,k<<1,l,mid,x,y); if(mid<=y) res+=query(tp,k<<1|1,mid+1,r,x,y); return res; } int main() { //ios::sync_with_stdio(false); cin.tie(0); scanf("%d%d%d",&l,&t,&o); //cin>>l>>t>>o; //for(int i=1;i<=t;i++) build(1,1,1,l); //cout<<o<<endl; for(int i=1;i<=o ;i++) { char s[3]; int a,b; scanf("%s%d%d",s,&a,&b); if(a>b) swap(a,b);// if(s[0]=='C'){ int v; scanf("%d",&v); for(int j=1;j<=t;j++){ if(j==v) change(j,1,1,l,a,b,1); else change(j,1,1,l,a,b,0); } } else{ int ans=0; for(int j=1;j<=t;j++) if(query(j,1,1,l,a,b)) ans++; printf("%d\n",ans); } } return 0; }

浙公网安备 33010602011771号