题目

晚上有n个亮着的灯泡,标号从1到n。

现在存在2种操作,如下:

  • 操作1,关掉标号 [l,r] 区间的灯
  • 操作2,打开标号 [l,r] 区间的灯

下面有q次询问,每次询问执行其中一种操作,询问格式,l,r,k,k为执行操作种类。对于每次询问回答当前开着的灯的数量。

Input

单组输入,第一行包含一个整数n,第二行一个整数q(1≤n≤10^9,1≤q≤3·10^5)

接下来q行每行3个整数表示询问,l,r,k(1 ≤ l ≤ r ≤ n, 1 ≤ k ≤ 2).

Output

对于每次询问回答一个整数占一行表示答案。

Example

Input
4
6
1 2 1
3 4 1
2 3 2
1 3 2
2 4 1
1 4 2
Output
2
0
2
3
1
4

题解:

因为线段树要开4倍空间。然而面对庞大的数据我们开maxn<<2的空间是肯定开不下的。

这时候就要用到动态开点线段树来节省空间了。( 或者离散化 )

动态开点也就是当用到那个节点的时候才给它分配空间,否则就不分配,就比如像这一道题n的大小是1e9,那么静态开点肯定炸空间了,,,但是你发现他询问的区间也就3e5个,可见用到的区间还是少数,所以每当用到一个区间我们再给他分配空间

动态开点线段树就是给你一个区间[1,n],按照普通线段树我们需要把线段树开到叶节点才结束(假设我们给一个长度为n的数组建一颗普通线段树,那么最后构造的线段树一个叶节点对应一个数组的一个值),

动态开点就是如果还没有用到具体那个点就不需要把线段树开到叶节点

代码:

 1 /*
2 动态开点线段树
3 */
4 #include<stdio.h>
5 #include<string.h>
6 #include<iostream>
7 #include<algorithm>
8 #include<queue>
9 #include<vector>
10 using namespace std;
11 const int maxn=3e5+10;
12 const int INF=0x3f3f3f3f;
13 typedef long long ll;
14 struct Node
15 {
16 int l,r,sum,lazy;
17 Node()
18 {
19 l=0,r=0,sum=0,lazy=0;
20 }
21 } node[maxn*50];
22 int cnt=1; //开点的数量
23 void pushdown(int l,int r,int k) //k是父节点在数组中的序号
24 {
25 int mid=(l+r)>>1;
26 if(l!=r)
27 {
28 if(!node[k].l) node[k].l=++cnt;
29 if(!node[k].r) node[k].r=++cnt;
30
31 if(node[k].lazy==2)
32 {
33 node[node[k].l].sum=node[node[k].r].sum=0;
34 }
35 else
36 {
37 node[node[k].l].sum=mid-l+1;
38 node[node[k].r].sum=r-mid;
39 }
40 node[node[k].l].lazy=node[k].lazy;
41 node[node[k].r].lazy=node[k].lazy;
42 }
43 node[k].lazy=0;
44 }
45 //往线段树里面插入一个区间[L,R]
46 void Insert(int l,int r,int &k,int L,int R,int p)
47 {
48 if(!k) k=++cnt; //这个k也就相当于我们要对node[k]这个节点进行操作
49 //node[1]是根节点,因为我们这是动态开点,所以没有开点的节点都是初始值0
50 if(l>=L && r<=R) //如果满足这个条件也就不需要pushdown,因为我们不需要下面节点就可以得到[l,r]区间内的答案
51 {
52 if(p==2) node[k].sum=0;
53 else node[k].sum=r-l+1;
54 node[k].lazy=p;
55 return;
56 }
57 //如果不满足上面那个判断,那么我们就要递归进入k的左右子节点,这个时候,你要保证左右子点都已经被修改好了
58 //即,懒惰标记lazy是0
59 if(node[k].lazy) pushdown(l,r,k);
60 int mid=(l+r)>>1;
61 if (mid>=L) Insert(l,mid,node[k].l,L,R,p);
62 if (mid<R) Insert(mid+1,r,node[k].r,L,R,p);
63 node[k].sum=node[node[k].l].sum+node[node[k].r].sum;
64 }
65 int main()
66 {
67 //printf("%d %d\n",node[1].l,node[1].r);
68 int n,q;
69 scanf("%d %d",&n,&q);
70 int k=1;
71 for (int i=1; i<=q; i++)
72 {
73 int l,r,p;
74 scanf("%d %d %d",&l,&r,&p);
75 Insert(1,n,k,l,r,p);
76 printf("%d\n",n-node[1].sum);
77 }
78 return 0;
79 }

CodeForces - 915E 动态开点线段树的更多相关文章

  1. Physical Education Lessons CodeForces - 915E (动态开点线段树)

    Physical Education Lessons CodeForces - 915E This year Alex has finished school, and now he is a fir ...

  2. codeforces 915E - Physical Education Lessons 动态开点线段树

    题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...

  3. codeforces 893F - Physical Education Lessons 动态开点线段树合并

    https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...

  4. Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树

    思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用  lazy=0 没被覆盖过 els ...

  5. [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)

    题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...

  6. [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...

  7. 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化

    4636: 蒟蒻的数列 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 247  Solved: 113[Submit][Status][Discuss ...

  8. CF915E Physical Education Lessons 动态开点线段树

    题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...

  9. 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)

    题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

随机推荐

  1. Java多线程-锁的区别与使用

    目录 锁类型 可中断锁 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级锁/重量级锁 自旋锁 Synchronized与Static Synchron ...

  2. AttGAN: Facial Attribute Editing by Only Changing What You Want 论文阅读笔记和AttGan的pytorch代码实现

    1.总体框架 上面的过程用详细描述即是 Test阶段: Train阶段: 由于我们无法得知编辑后的image,所以显而易见人脸属性编辑是一个无监督问题,而对于我们的xa需要获得关于b的属性,故利用at ...

  3. Github Python计算器开源项目 二次开发--增加函数图形

    先上原项目链接:https://github.com/xhf79/Calculator_pyqt python+Qt 开发的计算器 原项目界面和功能如图所示: 科学计算的内容基本都有,但按照项目的提示 ...

  4. bash shell数组使用总结

    本文为原创博文,转发请注明原创链接:https://www.cnblogs.com/dingbj/p/10090583.html  数组的概念就不多说了,大家都懂! shell数组分为索引数组和关联数 ...

  5. 一文读懂 TKE 及 Kubernetes 访问权限控制

    你有了解过Kubernetes的认证授权链路吗?是否对TKE的权限控制CAM策略.服务角色傻傻分不清楚?本文将会向你介绍腾讯云TKE平台侧的访问控制.Kubernetes访问控制链路,以及演示如何将平 ...

  6. RocketMq消息 demo

    参考 https://blog.csdn.net/asdf08442a/article/details/54882769 整理出来的测试 demo 1.produce 生产者 1 package co ...

  7. [Usaco2008 Feb]Line连线游戏

    题目描述 Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 <= N <= 200)个不重合的点的木板,其中第i个点 的横.纵 ...

  8. Nginx的简介和使用nginx实现请求转发

    一.什么是Nginx Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的.从2004年发布至今,凭借开源的力量,已经接近成熟与完善. Nginx功能丰富,可作为H ...

  9. 笔记 | pandas之时间序列学习随笔1

    1. 时间序列自动生成 ts = pd.Series(np.arange(1, 901), index=pd.date_range('2010-1-1', periods=900)) 最终生成了从20 ...

  10. Kubernetes集群管理工具kubectl命令技巧大全

    一. kubectl概述 Kubectl是用于控制Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署. kubectl命令的语法如下 ...