题意:给L长度的木板,给T种颜色,给O个操作,每次可以选择一段区间染色,或查询一个区间的颜色种类
思路:用线段树叶节点记录颜色所代表的数字,父节点为-1表示两个子节点颜色不相同,>0时的数字代表子节点全为这个数字对应颜色。
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxn=1e5+10; int a[maxn]; int l,t,o; int vis[35]; struct note { int left,right,sum,lazy; void up(int val) { sum=val; lazy=val; } } tree[maxn*4]; void pushup(int id) { if(tree[id<<1].sum==-1||tree[id<<1|1].sum==-1) tree[id].sum=-1; else if(tree[id<<1].sum==tree[id<<1|1].sum) tree[id].sum=tree[id<<1].sum; else tree[id].sum=-1; } void pushdown(int id) { if(tree[id].lazy) { tree[id<<1].up(tree[id].lazy); tree[id<<1|1].up(tree[id].lazy); tree[id].lazy=0; } } void build(int id,int l,int r) { tree[id].left=l; tree[id].right=r; if(l==r) tree[id].sum=1; else { int mid=(l+r)/2; build(id<<1,l,mid); build(id<<1|1,mid+1,r); pushup(id); } } void query(int id,int l,int r) { if(tree[id].sum!=-1) { vis[tree[id].sum]=1; return; } // pushdown(id); int mid=(tree[id].left+tree[id].right)/2; if(l<=mid) query(id<<1,l,r); if(r>mid) query(id<<1|1,l,r); } void update(int id,int l,int r,int val) { if(l<=tree[id].left&&tree[id].right<=r) { tree[id].up(val); return; } pushdown(id); int mid=(tree[id].left+tree[id].right)/2; if(l<=mid) update(id<<1,l,r,val); if(r>mid) update(id<<1|1,l,r,val); pushup(id); } int main() { scanf("%d%d%d",&l,&t,&o); build(1,1,l); for(int i=1; i<=o; i++) { char op; getchar(); scanf("%c",&op); if(op==‘C‘) { int l,r,color; scanf("%d%d%d",&l,&r,&color); update(1,l,r,color); } else { int l,r; scanf("%d%d",&l,&r); memset(vis,0,sizeof(vis)); query(1,l,r); int ans=0; for(int i=1; i<=30; i++) { if(vis[i]) ans++; } printf("%d\n",ans); } } }
原文地址:https://www.cnblogs.com/dongdong25800/p/11620054.html
时间: 2024-10-04 23:22:43