codevs 1690 开关灯 线段树 解题报告
2017-09-25 16:25
489 查看
彩蛋
题目描述 Description
YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N)输入描述 Input Description
第 1 行: 用空格隔开的两个整数N和M第 2..M+1 行: 每行表示一个操作, 有三个用空格分开的整数: 指令号(0代表按下开关,1代表询问状态), x 和 y
输出描述 Output Description
第 1..询问总次数 行:对于每一次询问,输出询问的结果
样例输入 Sample Input
4 50 1 2
0 2 4
1 2 3
0 2 4
1 1 4
样例输出 Sample Output
12
数据范围及提示 Data Size & Hint
一共4盏灯,5个操作,下面是每次操作的状态(X代表关上的,O代表开着的):XXXX -> OOXX -> OXOO -> 询问1~3 -> OOXX -> 询问1~4
思路
这种“区间复制修改查询”类题目,肯定是线段树。打好修改标记就好了。
代码
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cstdlib> using namespace std; struct os { int yes,total; bool flag; }tree[400010]; int n,m; int k,head,tail; void f(int root) { tree[root].yes=tree[root].total-tree[root].yes; } void build(int root,int begin,int end) { if (begin>end) return; tree[root].total=end-begin+1; if (begin==end) return; int mid=(begin+end)/2; build(root*2,begin,mid); build(root*2+1,mid+1,end); } void pushdown(int root) { if (!tree[root].flag) return; tree[root*2].flag=!tree[root*2].flag; tree[root*2+1].flag=!tree[root*2+1].flag; f(root*2); f(root*2+1); tree[root].flag=0; } void update(int root,int begin,int end) { if (begin>=head&&end<=tail) {f(root);tree[root].flag=!tree[root].flag;return;} pushdown(root); int mid=(begin+end)/2; if (head<=mid) update(root*2,begin,mid); if (tail>mid) update(root*2+1,mid+1,end); tree[root].yes=tree[root*2].yes+tree[root*2+1].yes; } int get(int root,int begin,int end) { if (begin>=head&&end<=tail) return tree[root].yes; pushdown(root); int mid=(begin+end)/2,ans=0; if (head<=mid) ans+=get(root*2,begin,mid); if (tail>mid) ans+=get(root*2+1,mid+1,end); return ans; } int main() { scanf("%d%d",&n,&m); build(1,1,n); for (int i=1;i<=m;i++) { scanf("%d%d%d",&k,&head,&tail); if (k==0) update(1,1,n); else printf("%d\n",get(1,1,n)); } return 0; }
相关文章推荐
- CodeVS1690 开关灯 解题报告【数据结构】【线段树】
- codevs 1690 开关灯 线段树水题
- Codevs_1690_开关灯_(线段树)
- 【codevs1690】开关灯,线段树练习
- codevs 1690 开关灯 线段树
- codevs1690 开关灯(线段树)
- CodeVS1369 xth 砍树 解题报告【数据结构】【线段树/树状数组】
- 【codevs1690】开关灯【线段树】
- 【codevs1690】开关灯 线段树 区间修改+区间求和(标记)
- 线段树--codevs 1690 开关灯
- Codevs 题目1690 开关灯(线段树区间异或)
- 【codevs1690】开关灯 线段树
- Codeforces Round #43 D题Parking Lot (线段树)解题报告
- codevs1690 开关灯
- codevs1690开关灯
- CodeVS3327 选择数字 解题报告【单调队列优化DP】
- codevs 1219 骑士游历 DP 解题报告
- codevs 1052 地鼠游戏 堆优化贪心 解题报告
- 习题:codevs 2822 爱在心中 解题报告
- CodeVS1219 骑士游历 解题报告【棋盘型DP】