某线段树题=。=

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

猜你喜欢

转载自blog.csdn.net/Bluelanzhan/article/details/82951469