洛谷 P1558 色板遊戲
阿新 • • 發佈:2019-02-10
spa 數據 show %s scan += 觀察 class inline
傳送門:洛谷 P1558 色板遊戲
算法分析:觀察到數據範圍:\(1\leq T\leq 30\) ,考慮使用二進制來進行狀態壓縮
將顏色\(x\)表示為 \(1<<(x-1)\) 即 \(2^{x-1}\),使用線段樹動態維護即可
#include<iostream> #include<cstdio> #define maxN 100010 #define ls k<<1 #define rs k<<1 | 1 #define mid ((l+r)>>1) using namespace std; typedef long long ll; ll sum[maxN*4+1],v[maxN*4+1]; int n,m,x,y,z,T; char op[3]; void pushdown(int,int,int),pushup(int); ll query(int,int,int,int,int); void update(int,int,int,int,int,int); void print(ll); void build(int,int,int); int main() { scanf("%d%d%d",&n,&T,&m); build(1,1,n); for(int i=1;i<=m;i++) { scanf("%s%d%d",op,&x,&y); if(op[0]==‘C‘) { scanf("%d",&z); update(1,1,n,min(x,y),max(x,y),1<<(z-1)); } else print(query(1,1,n,min(x,y),max(x,y))); } return 0; } void build(int k,int l,int r) { if(l==r) {sum[k]=1; return;} build(ls,l,mid); build(rs,mid+1,r); pushup(k); } void print(ll x) { int sum=0; while(x) {sum+=(x&1); x>>=1;} printf("%d\n",sum); } void pushup(int k) {sum[k]=sum[ls]|sum[rs];} void pushdown(int k,int l,int r) { v[ls]=v[rs]=sum[ls]=sum[rs]=v[k]; v[k]=0; } void update(int k,int l,int r,int ql,int qr,int u) { if(ql<=l && r<=qr) { sum[k]=u; v[k]=u; return; } if(v[k]) pushdown(k,l,r); if(ql<=mid) update(ls,l,mid,ql,qr,u); if(qr>mid) update(rs,mid+1,r,ql,qr,u); pushup(k); } long long query(int k,int l,int r,int ql,int qr) { if(ql<=l && r<=qr) return sum[k]; long long ans=0; if(v[k]) pushdown(k,l,r); if(ql<=mid) ans|=query(ls,l,mid,ql,qr); if(qr>mid) ans|=query(rs,mid+1,r,ql,qr); return ans; }
洛谷 P1558 色板遊戲