POJ 2777 Count Color
タイトルリンク:http://poj.org/problem?id=2777
标题:一面の長さlenの壁を与えて、最初の色は1で、2種類の操作を行って、1つは[l,r]を色pに塗って、2つは[l,r]区間に全部で何種類の色があるかを尋ねることです
考え方:区間の修正や問い合わせをすると線分樹を使いやすいのですが、どのくらいの色を保存しているのでしょうか、色が30種類未満なので(私はまた題解を見ました)、ビット演算で状態圧縮ができますが、残りは線分樹の普通の区間の修正と更新です(問題を書くときに花式が間違っていて、夜は興奮しすぎたでしょう......)
标题:一面の長さlenの壁を与えて、最初の色は1で、2種類の操作を行って、1つは[l,r]を色pに塗って、2つは[l,r]区間に全部で何種類の色があるかを尋ねることです
考え方:区間の修正や問い合わせをすると線分樹を使いやすいのですが、どのくらいの色を保存しているのでしょうか、色が30種類未満なので(私はまた題解を見ました)、ビット演算で状態圧縮ができますが、残りは線分樹の普通の区間の修正と更新です(問題を書くときに花式が間違っていて、夜は興奮しすぎたでしょう......)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100030
using namespace std;
struct Tree
{
int l,r,date;
}tree[maxn*3];
int lazy[maxn*3];
void build(int root,int l,int r)
{
tree[root].l=l;
tree[root].r=r;
if (l==r)
{
tree[root].date=(1<<1);
return;
}
int mid=(l+r)>>1;
build (root<<1,l,mid);
build (root<<1|1,mid+1,r);
tree[root].date=tree[root<<1].date|tree[root<<1|1].date;
}
void update(int root,int l,int r,int val)
{
if (tree[root].l>=l && tree[root].r<=r)
{
tree[root].date=(1<<val);
lazy[root]=(1<<val);
return;
}
if (lazy[root]!=0)
{
tree[root<<1].date=tree[root].date;
tree[root<<1|1].date=tree[root].date;
lazy[root<<1]=lazy[root];
lazy[root<<1|1]=lazy[root];
lazy[root]=0;
}
int mid=(tree[root].l+tree[root].r)>>1;
if (l<=mid) update(root<<1,l,r,val);
if (r>mid) update(root<<1|1,l,r,val);
tree[root].date=tree[root<<1].date|tree[root<<1|1].date;
}
int que(int root,int l,int r)
{
if (lazy[root]!=0) return lazy[root];
if (tree[root].l==l && tree[root].r==r)
return tree[root].date;
int mid=(tree[root].l+tree[root].r)>>1;
if (r<=mid) return que(root<<1,l,r);
else if (l>mid) return que(root<<1|1,l,r);
else return que(root<<1,l,mid)|que(root<<1|1,mid+1,r);
}
int main()
{
int len,n,m;
while (scanf("%d%d%d",&len,&n,&m)!=EOF)
{
memset(lazy,0,sizeof(lazy));
build (1,1,len);
for (int i=0;i<m;i++)
{
char tem;
cin>>tem;
if (tem=='C')
{
int a,b,p;
scanf("%d%d%d",&a,&b,&p);
if (a>b) swap(a,b);
update(1,a,b,p);
}
else
{
int a,b,res=0,cl;
scanf("%d%d",&a,&b);
if (a>b) swap(a,b);
cl=que(1,a,b);
// cout<<":"<<cl<<endl;
for (int i=1;i<=n;i++)
{
if ((cl&(1<<i))!=0) res++;
}
printf("%d
",res);
}
}
}
}