题目描述

  $D$先生,是一个了不起的甜甜圈制造商。今天,他的厨房准备在日出之前制作甜甜圈。$D$先生瞬间完成了$N$个油炸圈饼。但是,这些油炸圈饼得先经过各种装饰任务才可以成为甜甜圈销售:填充奶油,浸入巧克力,打顶可爱,丰富多彩的东西等等。
  装饰任务有$K$个,任务编号为$1$到$K$,并且每一个甜甜圈都必须严格按照$K$个任务以$1,2,...,K$的顺序仅完成一次,才能成为销售物品。
  $D$先生将$N$个甜甜圈排成一列,他似乎打算一次完成每个装饰任务。但是,昨天晚上熬夜的$D$先生每个任务只装饰了部分连续区间的甜甜圈。这显然是一个错误!不仅如此,他还可能是做了几次同一任务,任务的顺序也是混乱的。
  没有经过正确流程装饰的甜甜圈不能作为销售物品提供,所以他应该把它们丢掉。幸运的是,有数据依次记录了他所做的一系列任务。数据包含以下信息:对于每个任务,装饰的甜甜圈的连续区间$[l,r]$和任务的$ID\ x$。
  请编写一个程序,列举可在展示柜中显示的甜甜圈的数量,作为销售给定记录数据的答案。


输入格式

第一行两个整数$N$和$K$,表示有$N$个甜甜圈和$K$个任务。
第二行一个整数$T$,表示$D$先生依次完成了$T$个区间的装饰。
接下来$T$行,每行三个正整数$l_i,r_i,x_i$,分别表示区间$[l_i,r_i]$的甜甜圈完成了$ID$为$x_i$的装饰任务。


输出格式

一个整数,表示能作为展示的甜甜圈的数量。


样例

样例输入:

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

样例输出:

1


数据范围与提示

样例解释:

$1$号甜甜圈没有完成任务$1$就完成了任务$2$所以抛弃,$3$号甜甜圈的任务$2$被重复完成了$2$次,抛弃!$4$号甜甜圈先完成了任务$3$再完成任务$2$,抛弃!$5$号甜甜圈没有完成任务$3$,抛弃!所以只有$2$可以展示。

数据范围:

对于$40\%$的数据,$N,K,T\leqslant 5,000$
对于另外$20\%$的数据,$K\leqslant 100$
对于另外$10\%$的数据,$l_i=r_i$
对于$100\%$的数据,$1\leqslant N,K,T\leqslant 200,000,x_i\leqslant K,1\leqslant l_i\leqslant r_i\leqslant N$


题解

显然是一道线段树,我们考虑如何维护。

用两个懒标记,分别表示其上端点和下端点,$-1$表示没有懒标记,$-2$表示这段区间已经不合法即可。

最后将整棵树跑一边即可统计答案。

时间复杂度:$\Theta(N\log N+T\log N)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
int N,K,T;
int tr[1000000],lz1[1000000],lz2[1000000];
int ans;
void build(int x,int l,int r)
{
lz1[x]=lz2[x]=-2;
if(l==r)return;
int mid=(l+r)>>1;
build(L(x),l,mid);
build(R(x),mid+1,r);
}
void pushdown(int x)
{
if(lz1[x]==-2)return;
if(lz1[x]==-1)
{
tr[L(x)]=tr[R(x)]=lz1[L(x)]=lz1[R(x)]=lz2[L(x)]=lz2[R(x)]=-1;
return;
}
if(tr[L(x)]!=-1)
{
if(tr[L(x)]+1==lz1[x])tr[L(x)]=lz2[x];
else tr[L(x)]=-1;
}
if(tr[R(x)]!=-1)
{
if(tr[R(x)]+1==lz1[x])tr[R(x)]=lz2[x];
else tr[R(x)]=-1;
}
if(lz1[L(x)]!=-1)
{
if(lz1[L(x)]==-2){lz1[L(x)]=lz1[x];lz2[L(x)]=lz2[x];}
else if(lz2[L(x)]+1==lz1[x])lz2[L(x)]=lz2[x];
else lz1[L(x)]=lz2[L(x)]=-1;
}
if(lz1[R(x)]!=-1)
{
if(lz1[R(x)]==-2){lz1[R(x)]=lz1[x];lz2[R(x)]=lz2[x];}
else if(lz2[R(x)]+1==lz1[x])lz2[R(x)]=lz2[x];
else lz1[R(x)]=lz2[R(x)]=-1;
}
lz1[x]=lz2[x]=-2;
}
void change(int x,int l,int r,int L,int R,int w)
{
if(r<L||R<l)return;
if(L<=l&&r<=R)
{
if(tr[x]!=-1)
{
if(tr[x]+1==w)tr[x]++;
else tr[x]=-1;
}
if(lz1[x]!=-1)
{
if(lz1[x]==-2)lz1[x]=lz2[x]=w;
else if(lz2[x]+1==w)lz2[x]++;
else lz1[x]=lz2[x]=-1;
}
return;
}
pushdown(x);
int mid=(l+r)>>1;
change(L(x),l,mid,L,R,w);
change(R(x),mid+1,r,L,R,w);
}
void ask(int x,int l,int r)
{
if(l==r)
{
if(tr[x]==K)ans++;
return;
}
pushdown(x);
int mid=(l+r)>>1;
ask(L(x),l,mid);
ask(R(x),mid+1,r);
}
int main()
{
scanf("%d%d%d",&N,&K,&T);
build(1,1,N);
while(T--)
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
change(1,1,N,l,r,x);
}
ask(1,1,N);
printf("%d",ans);
return 0;
}

rp++

最新文章

  1. Hadoop学习笔记——搭建
  2. 微软Dynamics 使用葡萄城的Wijmo 5提供移动端用户界面选择
  3. Facebook开源动画库 POP-POPSpringAnimation运用
  4. VMware技巧01
  5. 在Windows/Ubuntu下安装OpenGL环境(GLUT/freeglut)与跨平台编译(mingw/g++)
  6. [codevs 1995]黑魔法师之门(并查集)
  7. 如何在Eclipse中查看Android源码或者第三方组件包源码
  8. Find Minimum in Rotated Sorted Array II
  9. Codeforces 505 A Mr. Kitayuta&#39;s Gift【暴力】
  10. Hadoop应用开发实战案例 第1周
  11. hadoop各版本下载
  12. Python基础第三天
  13. 51nod1138(math)
  14. eclipse报错 : One or more constraints have not been satisfied.
  15. 极致21点开发DAY4
  16. Zuul过滤器
  17. 安装office2010提示要安装MSXML6.10.1129.0解决方法
  18. linux shell 学习笔记01
  19. 使用MyEclipse开发Java EE应用:EJB项目开发初探(下)
  20. [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)

热门文章

  1. TestNG 多线程测试
  2. Krustal重构树
  3. vue子组件修改父组件传递过来的值
  4. 前端 CSS 一些标签默认有padding
  5. [Python3] 014 集合的内置方法
  6. HTML: 引号不能忽视
  7. Centos6.8忘记MySQL数据库root密码解决方法
  8. hive Hbase sql
  9. Eclipse解除已关联的Coding远程仓库,重新关联github上的远程仓库
  10. Django中orm的惰性机制