时隔2天才搞定, 哎, 最近各种忙啊, 忙得晕头转向。
明显的线段树, 对于搞过状态压缩的, 一看到颜色为1~30, 于是马上想起了位运算, 这题需要成段更新, 不然绝对的超时, 其余的按照模板来就行了。
#include<cstdio>
#include<cstring>
#include<iostream>
#define L(u) (u<<1)
#define R(u) (u<<1|1)
using namespace std;
const int N = 100005;
int color[32];
struct Node {
int l, r, color;
bool flag;
} node[N<<2];
void ini()
{
color[1] = 1;
for(int i=2; i<=30; ++i)
color[i] = color[i-1]<<1;
}
void pushUp(int u)
{
node[u].color = node[L(u)].color | node[R(u)].color;
}
void pushDown(int u)
{
node[u].flag = false;
node[L(u)].color = node[u].color;
node[L(u)].flag = true;
node[R(u)].color = node[u].color;
node[R(u)].flag = true;
}
void build(int u,int left,int right)
{
node[u].l = left, node[u].r = right;
node[u].color = 1;
node[u].flag = false;
if(node[u].l==node[u].r)
{
node[u].flag = true;
return;
}
int mid = (node[u].l+node[u].r)>>1;
build(L(u), left, mid);
build(R(u), mid+1, right);
}
void upDate(int u,int left,int right,int val)
{
if(left<=node[u].l&&node[u].r<=right)
{
node[u].flag = true;
node[u].color = val;
return;
}
if(node[u].color == val)
{
return;
}
if(node[u].flag)
{
pushDown(u);
}
int mid = (node[u].l+node[u].r)>>1;
if(right<=mid) upDate(L(u),left,right,val);
else if(left>mid) upDate(R(u),left,right,val);
else
{
upDate(L(u),left,mid,val);
upDate(R(u),mid+1,right,val);
}
pushUp(u);
}
void query(int u,int left,int &sum,int right)
{
if(node[u].flag)
{
sum |= node[u].color;
return;
}
if(left<=node[u].l&&node[u].r<=right)
{
sum |= node[u].color;
return;
}
int mid = (node[u].l+node[u].r)>>1;
if(right<=mid)
query(L(u),left,sum,right);
else if(left>mid)
{
query(R(u),left,sum,right);
}
else
{
query(L(u),left,sum,mid);
query(R(u),mid+1,sum,right);
}
}
int judge(int sum) {
int ans = 0;
while(sum){
if(sum % 2) ans ++;
sum = sum>>1;
}
return ans;
}
int main(void)
{
int l, t, o;
char str[2];
scanf("%d%d%d",&l,&t,&o);
ini();
build(1, 1, l);
while(o--)
{
scanf("%s",str);
if(str[0] == 'P')
{
int ans =0;
int a,b;
scanf("%d%d",&a,&b);
if(a < b)
query(1,a,ans,b);
else
query(1,b,ans,a);
printf("%d\n",judge(ans));
}
else
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a < b)
upDate(1,a,b,color[c]);
else
upDate(1,b,a,color[c]);
}
}
return 0;
}