题目:POJ-2777
题意:给出n的长度的木棒,初始的颜色都为1,给出num中颜色,给出m个操作, C l r x 将l到r内的所有颜色更改为x , P l r 问在l到r内有多少种颜色
题解:初始化肯定都是颜色1,就表示只有一种颜色,然后每次更新颜色时,取这个数的a[x]=1<<(Item-1),a[x]中的1的位置就表示每个颜色的位置,那么这样或过去就可以查找出有多少种颜色了
然后pushup操作就改为:a[x]=a[x*2]|a[x*2+1],a[x]中的1的个数就是这个区间颜色的个数。对于Item为什么要-1,其实就是初始颜色时1,就相当于从第0位开始,与数组的0-n-1类似。
最后注意不要用ans1|ans2(其中ans1跟ans2是自己定义的变量),因为这样居然RE了,感觉天衣无缝
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 110000
#define lson node<<1
#define rson node<<1|1
using namespace std;
int n,k,m;
struct ljh
{
int l,r,sum,lazy;
}e[N*4];
void pushup(int node)
{
e[node].sum=(e[lson].sum|e[rson].sum);
}
void pushdown(int node)
{
if(e[node].lazy!=0)
{
e[lson].sum=e[node].lazy;
e[lson].lazy=e[node].lazy;
e[rson].sum=e[node].lazy;
e[rson].lazy=e[node].lazy;
e[node].lazy=0;
}
}
void build(int node,int l,int r)
{
e[node].l=l;
e[node].r=r;
e[node].sum=0;
e[node].lazy=0;
if(l==r)
{
e[node].sum=1;
return ;
}
int m=(l+r)>>1;
build(lson,l,m);
build(rson,m+1,r);
pushup(node);
}
void update(int node,int x,int y,int z)
{
if(x<=e[node].l&&e[node].r<=y)
{
e[node].sum=1<<(z-1);
e[node].lazy=1<<(z-1);
return ;
}
pushdown(node);
int m=(e[node].l+e[node].r)>>1;
if(x<=m)update(lson,x,y,z);
if(y>m)update(rson,x,y,z);
pushup(node);
}
int query(int node,int x,int y)
{
if(e[node].l>y||e[node].r<x)
{
return 0;
}
// int ans=0,sum=0;
if(x<=e[node].l&&e[node].r<=y)
{
return e[node].sum;
}
pushdown(node);
// if(x<=m)ans=query(lson,x,y);
// if(y>m)sum=query(rson,x,y);
// return (ans|sum);
return query(lson,x,y)|query(rson,x,y);
}
int ans(int x)
{
int temp=0;
// cout<<x<<endl;
while(x)
{
// cout<<x<<endl;
if(x&1)temp++;
x>>=1;
}
return temp;
}
int main()
{
while(~scanf("%d%d%d",&n,&k,&m))
{
build(1,1,n);
while(m--)
{
char op;
int x,y,z;
// getchar();
cin>>op;
// cout<<op<<endl;
if(op=='C')
{
scanf("%d%d%d",&x,&y,&z);
if(x>y)swap(x,y);
update(1,x,y,z);
}
if(op=='P')
{
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
printf("%d\n",ans(query(1,x,y)));
}
}
}
return 0;
}
附上之前写T了的代码,虽然不知道为啥会T,感觉跟AC代码比起来,查找的时间复杂度差不多???甚至还快些???
T了的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<algorithm>
#define N 100005
#define lson node<<1
#define rson node<<1|1
using namespace std;
int L,m,n,vis[35],ans;
struct ljh
{
int l,r,sum;
}e[N<<2];
void build(int node,int l,int r)
{
// cout<<l<<" "<<r<<endl;
e[node].sum=1;
e[node].l=l;
e[node].r=r;
if(l==r)return ;
int m=(l+r)>>1;
build(lson,l,m);
build(rson,m+1,r);
}
void pushdown(int node)
{
if(e[node].sum!=-1)
{
e[lson].sum=e[node].sum;
e[rson].sum=e[node].sum;
e[node].sum=-1;
}
}
void pushup(int node)
{
if(e[lson].sum==e[rson].sum)
e[node].sum=e[lson].sum;
}
void update(int node,int x,int y,int z)
{
// cout<<node<<endl;
if(x<=e[node].l&&e[node].r<=y)
{
e[node].sum=z;
return;
}
pushdown(node);
int m=(e[node].l+e[node].r)>>1;
if(x<=m)update(lson,x,y,z);
if(y>m)update(rson,x,y,z);
pushup(node);
}
void query(int node,int x,int y)
{
// cout<<node<<" "<<e[node].l<<" "<<e[node].r<<" "<<e[node].sum<<endl;
if(e[node].sum!=-1&&!vis[e[node].sum])
{
ans++;
vis[e[node].sum]=1;
return;
}
if(e[node].l==e[node].r)return;
pushdown(node);
int m=(e[node].l+e[node].r)>>1;
if(x<=m)query(lson,x,y);
if(y>m)query(rson,x,y);
pushup(node);
}
int main()
{
while(~scanf("%d%d%d",&L,&n,&m))
{
build(1,1,L);
while(m--)
{
char op;
int x,y,z;
// getchar();
cin>>op;
// cout<<op<<endl;
if(op=='C')
{
scanf("%d%d%d",&x,&y,&z);
// if(x>y)swap(x,y);
update(1,x,y,z);
}
if(op=='P')
{
memset(vis,0,sizeof(vis));
scanf("%d%d",&x,&y);
ans=0;
// if(x>y)swap(x,y);
query(1,x,y);
printf("%d\n",ans);
}
}
}
}