FOJ 1968 Twinkling lights III

    技术2025-10-16  3

    线段树,嗯,嗯。

     

    本题有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; }  

    最新回复(0)