[line tree] switch (luogu 3870)

switch

luogu 3870

Main idea:

There are n lights. Each time, press all the lights in a section (on / off, off / on, operation 0), or ask how many lights in a section are on (operation 2), press the operation, output

Input example ා 1:

4 5
0 1 2
0 2 4
1 2 3
0 2 4
1 1 4

Output example:

1
2

Solutions:

Use the line tree, and then switch on and off the lights, i.e. add 1 and then module 2 each time. If the whole section, directly subtract the number of lights by the length of the section.

Code:

#include<cstdio>
using namespace std;
int n,m,u,x,y;
struct rec
{
    int l,r,num,lazy;
}tree[400500];
void make(int dep)//Build up trees
{
    if (tree[dep].l==tree[dep].r) return;
    int mid=(tree[dep].l+tree[dep].r)>>1;
    tree[dep*2].l=tree[dep].l,tree[dep*2].r=mid;
    tree[dep*2+1].l=mid+1,tree[dep*2+1].r=tree[dep].r;
    make(dep*2);
    make(dep*2+1);
    return;
}
void pass(int dep)//Downward transmission
{
    if (tree[dep].lazy)
      {
      	tree[dep*2].lazy^=1;//Take inverse
        tree[dep*2+1].lazy^=1;
        tree[dep*2].num=tree[dep*2].r-tree[dep*2].l+1-tree[dep*2].num;//Take inverse
        tree[dep*2+1].num=tree[dep*2+1].r-tree[dep*2+1].l+1-tree[dep*2+1].num;
        tree[dep].lazy=0;
      }
}
void change(int dep,int l,int r)
{
    if (tree[dep].l==l&&tree[dep].r==r)//Here we are
      {
      	tree[dep].num=tree[dep].r-tree[dep].l+1-tree[dep].num;//Take inverse
      	tree[dep].lazy^=1;
      	return;
      }
    if (tree[dep].l>=tree[dep].r) return;
    pass(dep);
    int mid=(tree[dep].l+tree[dep].r)>>1;
    if (r<=mid)//All on the left side.
      {
      	change(dep*2,l,r);
      	tree[dep].num=tree[dep*2].num+tree[dep*2+1].num;
      	return;
      }
    if (l>mid)
      {
      	change(dep*2+1,l,r);
      	tree[dep].num=tree[dep*2].num+tree[dep*2+1].num;
      	return;
      }
    change(dep*2,l,mid);
    change(dep*2+1,mid+1,r);
    tree[dep].num=tree[dep*2].num+tree[dep*2+1].num;
    return;
}
int find(int dep,int l,int r)//query
{
    if (tree[dep].l==l&&tree[dep].r==r) return tree[dep].num;
    if (tree[dep].l>=tree[dep].r) return 0;
    pass(dep);
    int mid=(tree[dep].l+tree[dep].r)>>1;
    if (r<=mid) return find(dep*2,l,r);
    if (l>mid) return find(dep*2+1,l,r);
    return find(dep*2,l,mid)+find(dep*2+1,mid+1,r);
}
int main()
{
    scanf("%d %d",&n,&m);
    tree[1].l=1;
    tree[1].r=n;
    make(1);
    for (int i=1;i<=m;++i)
      {
      	scanf("%d %d %d",&u,&x,&y);
      	if (!u) change(1,x,y);//Operation 1
      	else printf("%d\n",find(1,x,y));
      }
}

Posted by partypete on Fri, 01 Nov 2019 02:28:22 -0700