ABC-At Least One-(预处理+树状数组)

E

题意:
就是给你n个卡牌,每个卡牌两个数字,数字的大小都<=m。定义f(i)为,长度为i且连续的一段子序列,然后有多少给这样的子序列是好序列,好序列的概念就是,对于任意一张卡片,卡片上至少有一个数字在这个序列中。让你求出f(1),f(2)…f(m)。

思考:
首先是对每个长度i都求出来答案,如果枚举i,再去求有多少区间满足这是n*n的复杂度。所以只能是求出来合法区间之后再去更新所有答案。所以对每个点求出以这个点为左端点,右端点到哪可以满足所有卡牌。求这个可以O(n),因为每次只走一个,也就是左端点加1,那么右端点看看到底要到哪。到哪可以根据删去i这个点,看看i这个点包含多少点的左端点,那么这个卡牌的左端点没了,那么只能要右端点。如果一个卡牌的右端点也小于当前的i,那么后面的都不合法了,也就是有一个卡牌不满足。对于比如l,r这段区间可以,那么就让(r-l+1,m-l+1)这些f的答案加1。因为左端点就是l,右端点从r到m,能更新的区间就这些。这段区间的累加可以用线段树也可以用树状数组。
害,经典赛后几分钟过题,比赛的时候对于累加区间的范围的时候傻逼了。

代码:

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
		
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;

int T,n,m,k;
PII va[N];
int anw[N];

int tr[N],Rr = 2e5+5;

int bit(int x)
{
	return x&(-x);
}

void update(int x,int value)
{
	while(x<=Rr)
	{
		tr[x] += value;
		x += bit(x);
	}
}

int query(int x)
{
	int sum = 0;
	while(x)
	{
		sum += tr[x];
		x -= bit(x);
	}
	return sum;
}

set<int> s[N];

signed main()
{
	IOS;
	cin>>n>>m;
	int R = 0,minn = inf;
	for(int i=1;i<=n;i++)
	{
		cin>>va[i].fi>>va[i].se;
		R = max(R,va[i].fi); //刚开始的右端点要在哪
		s[va[i].fi].insert(i);
		minn = min(minn,va[i].se); //卡牌中最小的最大值
	}
	int suc = 1;
	for(int i=1;i<=m;i++)
	{
		if(!suc) break;
		int l = R-i+1,r = m-i+1;
		update(l,1);
		update(r+1,-1);
		int maxn = 0;
		for(auto t:s[i]) maxn = max(maxn,va[t].se); //看看右端点要到哪
		if(i+1>minn) suc = 0; //如果扔掉i点之后,某个卡牌的右端点也不在里面了,就不合法了
		R = max(R,maxn);
	}
	for(int i=1;i<=m;i++) cout<<query(i)<<" ";
	return 0;
}

总结:
注意细节,不要思考傻逼性的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值