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)); } }