2021正睿csp7连day1


交了钱的比赛呀,第一天的题其实整体上并不是非常难,暴力分还是不小的,如果都能拿到也不错了,奈何暴力分一分没有,我明白了 分段是如此重要,这次还有审题不清的锅,比如第二题数据范围没看清,导致只有10分骗分,就很难受。不多说了,开始正题吧。

数列

比赛ing

看到这道题,发现这个数列每次都是从最前面开始计算,符合先进先出,所以立马想到的是用两个队列,去交替进行操作。就是一道模拟题,比较水。

正解

好好打完了了之后是a了,正解告诉我要打表?你没听错,确实没什么可说的。无语子【笑哭】
(因为正解都没写,所以我也放弃了)

索引

比赛ing

看到这道题的时候,注意到了严格单调这几个字,于是凭借我打 a b c abc abc的经验(也没多少),我认为要找到某种性质。因为满足严格单调,所以要使有数字符合 a [ i ] = i a[i]=i a[i]=i,那么 a [ 1 ] a[1] a[1]在刚开始只能是1,后面才有机会,因为如果刚开始1就已经比1打了,说明后面无论怎么加都绝对不可能等于 i i i的。所以,这样想着,我完完全全走偏了,交上去了一份10分的代码(10分还是因为运气好)。错误原因就是,我没看清楚数据范围!!!!!啊【暴风哭泣】,比如 a [ 1 ] = − 100 a[1]=-100 a[1]=100之类的,之后加照样可以满足题意,而且 c c c也是会出现负数的,这个问题确实不应该犯,自罚【/(ㄒoㄒ)/~~】

正解

其实关注到严格单调这几个字,最容易让人想起的应该是二分吧。于是我们就可以用二分来写。二分符合题意的位置。如果 a [ m i d ] > m i d a[mid]>mid a[mid]>mid,则后面的数严格递增,一定不可能符合题意,<时同理。

那区间修改这个操作是比较费时间的呀,不过,恰好有一种数据结构可以完成区间修改的操作,那就是树状数组。只需要进行差分就足够了。

所以总结一下:这道题就是二分同时,利于树状数组进行差分区间修改,而且都是板子,拿不到分血亏。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+10;
int a[maxn],b[maxn],c[maxn],k,n;
void add(int id,int y)
{
   
	if(!id) return ;
	for(int x=id;x<n;x+=(x&-x)) c[x]+=y;
	return ;
}
int sum(int id)
{
   
	if(!id) return 0;
	int ans=0;
	for(int x=id;x;x-=(x&-x)) ans+=c[x];
	return ans;
}
void work()
{
   
	int l=1,r=n;
	while(l+1<r)
	{
   
		int mid=(l+r)/2;
		if(sum(mid)>0) r=mid;//此时树状数组维护的是a[i]与i的差值,所以应该和0比较
		else if(sum(mid)<0) l=mid;
		else
		{
   
			printf("YES\n");
			return ;</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值