您的位置:首页 > 其它

FOJ 1968 Twinkling lights III

2011-02-15 21:37 309 查看
线段树,嗯,嗯。

本题有5个操作,并且对象都是区间:1. 开灯 2.关灯 3.把开的关,关的打开 4.询问区间有几盏灯亮着 5.询问区间最多连续亮着几盏灯

结构体里的cov是否完全覆盖,-1表示未完全覆盖,0表示区间的灯都暗着,1表示区间灯都亮着。

#include <iostream>
using namespace std;
#define MAX 2000000
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define Mid(a,b) ((a+b)>>1)
int cnt,ri,k;
struct node{
int l,r,mid;
int cov;
}tree[MAX+10];
void build(int l,int r,int num)
{
tree[num].l=l;
tree[num].r=r;
tree[num].cov=1;
if(l==r)
return;
else
{
int mid=tree[num].mid=Mid(l,r);
build(l,mid,LL(num));
build(mid+1,r,RR(num));
}
}
void turn(int l,int r,int num,int ans)
{
if(ans==tree[num].cov)
return;
if(l==tree[num].l&&r==tree[num].r)
{
tree[num].cov=ans;
return;
}
if(tree[num].cov!=-1)
{
tree[LL(num)].cov=tree[RR(num)].cov=tree[num].cov;
tree[num].cov=-1;
}
int mid=tree[num].mid;
if(r<=mid)
turn(l,r,LL(num),ans);
else if(l>mid)
turn(l,r,RR(num),ans);
else
{
turn(l,mid,LL(num),ans);
turn(mid+1,r,RR(num),ans);
}
}
void change(int l,int r,int num)
{
if(tree[num].l==l&&tree[num].r==r)
{
if(tree[num].cov!=-1)
{
tree[num].cov^=1;
return;
}
}
if(tree[num].cov!=-1)
{
tree[LL(num)].cov=tree[RR(num)].cov=tree[num].cov;
tree[num].cov=-1;
}
int mid=tree[num].mid;
if(r<=mid)
change(l,r,LL(num));
else if(l>mid)
change(l,r,RR(num));
else
{
change(l,mid,LL(num));
change(mid+1,r,RR(num));
}
}
int count(int l,int r,int num)
{
if(tree[num].cov!=-1)
{
return (r-l+1)*tree[num].cov;
}
int mid=tree[num].mid;
if(r<=mid)
count(l,r,LL(num));
else if(l>mid)
count(l,r,RR(num));
else
return count(l,mid,LL(num))+count(mid+1,r,RR(num));
}
void query(int l,int r,int num)
{
if(tree[num].l==l&&tree[num].r==r)
{
if(tree[num].cov!=-1)
{
if(tree[num].cov==1)
{
if(l==ri+1)
cnt+=r-l+1;
else
cnt=r-l+1;
if(cnt>k)
k=cnt;
ri=r;
}
return;
}
}
if(tree[num].cov!=-1)
{
tree[LL(num)].cov=tree[RR(num)].cov=tree[num].cov;
}
int mid=tree[num].mid;
if(r<=mid)
query(l,r,LL(num));
else if(l>mid)
query(l,r,RR(num));
else
{
query(l,mid,LL(num));
query(mid+1,r,RR(num));
}
}
int main()
{
int n,m,i,l,r;
char ch;
while(scanf("%d%d",&n,&m)!=EOF)
{
build(1,n,1);
while(m--)
{
scanf(" %c%d%d",&ch,&l,&r);
if(ch=='C')
turn(l,r,1,0);
else if(ch=='S')
turn(l,r,1,1);
else if(ch=='A')
change(l,r,1);
else if(ch=='Q')
printf("%d/n",count(l,r,1));
else if(ch=='L')
{
k=cnt=0;
ri=-1;
query(l,r,1);
printf("%d/n",k);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: