Decription
D先生,是一个了不起的甜甜圈制造商。今天,他的厨房准备在日出之前制作甜甜圈。D先生瞬间完成了N个油炸圈饼。但是,这些油炸圈饼得先经过各种装饰任务才可以成为甜甜圈销售:填充奶油,浸入巧克力,打顶可爱,丰富多彩的东西等等。
装饰任务有K 个,任务编号为1 到K,并且每一个甜甜圈都必须严格按照K个任务以1,2,…,K 的顺序仅完成一次,才能成为销售物品。
D先生将 N个甜甜圈排成一列,他似乎打算一次完成每个装饰任务。但是,昨天晚上熬夜的D先生每个任务只装饰了部分连续区间的甜甜圈。这显然是一个错误!不仅如此,他还可能是做了几次同一任务,任务的顺序也是混乱的。
没有经过正确流程装饰的甜甜圈不能作为销售物品提供,所以他应该把它们丢掉。幸运的是,有数据依次记录了他所做的一系列任务。数据包含以下信息:对于每个任务,装饰的甜甜圈的连续区间[l,r] 和任务的ID x 。
请编写一个程序,列举可在展示柜中显示的甜甜圈的数量,作为销售给定记录数据的答案。
Input
第一行两个整数N和K,表示有N个甜甜圈和K个任务。
第二行一个整数T,表示D先生依次完成了T个区间的装饰。
接下来T行,每行三个正整数li,ri,xi,分别表示区间[li,ri]的甜甜圈完成了ID为xi的装饰任务。
Output
一个整数,表示能作为展示的甜甜圈的数量。
Sample Input 5 3 5 2 3 1 1 3 2 4 5 1 2 4 3 3 5 2
Sample Output 1
Hint
样例解释:1号甜甜圈没有完成任务1就完成了任务2所以抛弃,3号甜甜圈的任务2被重复完成了2次,抛弃!4号甜甜圈先完成了任务3再完成任务2,抛弃!5号甜甜圈没有完成任务3,抛弃!所以只有2可以展示。
对于40%的数据,N,K,T<=5000
对于另外20%的数据,K<=100
对于另外10%的数据,li=ri
对于100%的数据,1<=N,K,T<=200000,xi<=K, 1<=li<=ri<=N
这道题本来我的思路是区间和比原来多(r - l +1),但是废物区间没法传啊,会T的啊!!!,而且有些区间都是废物了,但维护区间和的时候不知道下面的是废物,pushdown会出错;
qurey 不需要update不回去的a;
mi,ma,vis//vis是不是废物。
#include<bits/stdc++.h>
using namespace std;
int mi[1600005], ma[1600005],tag[1600005], ans;
int vis[1600005], flag[1600005], n, k, a, b, c, t;
void read( int &x )
{
char c = getchar();
while( c < '0' || c > '9' )
{
c = getchar();
}
while( c >= '0' && c <= '9' )
{
x = 10 * x + c - '0';
c = getchar();
}
}
void pushdown(int o, int l, int r)
{
if(flag[o] == 1)
{
int mid = (l + r) >> 1;
flag[o] = 0;
flag[o*2] = flag[o*2+1] = 1;
mi[o*2] = mi[o*2+1] = ma[o*2] = ma[o*2+1] = tag[o];
tag[o*2] = tag[o * 2 + 1] = tag[o];
tag[o] = 0;
}
}
void update(int o)
{
if(vis[o*2] == 0 &&vis[o*2+1] == 0)
{
mi[o] = min(mi[o*2],mi[o*2+1]);
ma[o] = max(ma[o*2],ma[o*2+1]);
return ;
}
if(vis[o*2] == 1 &&vis[o*2+1] == 0)
{
mi[o] = mi[o*2+1];
ma[o] = ma[o*2+1];
return;
}
if(vis[o*2+1] == 1 && vis[o*2] == 0)
{
mi[o] = mi[o*2];
ma[o] = ma[o*2];
return ;
}
vis[o] = 1;
}
void modify(int o, int l, int r, int ql, int qr, int val)
{
if(vis[o] == 1) return ;
pushdown(o, l, r);
if(mi[o] == ma[o] && ql <= l && r <= qr )
{
if(val-1 != mi[o])
{
vis[o] = 1;
return;
}
mi[o] = ma[o] = val;
tag[o] = val;
flag[o] = 1;
return ;
}
int mid = (l + r) /2 ;
if(ql <= mid) modify(o * 2, l, mid, ql, qr, val);
if(qr > mid) modify(o * 2 + 1, mid + 1, r, ql, qr, val);
update(o);
}
int qurey(int o, int l, int r, int pos)
{
if(vis[o] == 1) return 0;
pushdown(o, l, r);
if(l == r)
{
if(mi[o] == k) return 1;
return 0;
}
int mid = (l + r) >> 1;
if(pos <= mid) return qurey(o * 2, l, mid, pos);
if(pos > mid) return qurey(o * 2 + 1, mid + 1, r, pos);
}
int main()
{
freopen("deco.in", "r", stdin);
freopen("deco.out", "w", stdout);
cin >> n >> k;
cin >> t;
for( int i = 1; i <= t; i++ )
{
a = 0, b = 0, c = 0;
read(a);read(b);read(c);
modify(1, 1, n, a, b, c);
}
for(int i = 1; i <= n; i++)
{
ans += qurey(1, 1, n, i);
}
cout <<ans;
return 0;
}