CF-936(AB)

CF-936(已更新:AB)

诶……今天还有一个积分赛……自己学科方面也满是坑要补……感觉自己前途一片灰暗/(ㄒoㄒ)/~~

A

分析

只要增大与初始序列中位数的值相同的数,就能在不改变序列顺序的情况下增大中位数的值

代码

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define db(x) cout<<x<<" "<<endl;
#define _db(a,n) for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl;
#define mem(a) memset(a,0, sizeof(a))
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
const int N=2e5+5;
int a[N];
void solve(){
	int n;cin>>n;
	rep(i,1,n){
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	int s=(n+1)/2;
	int ans=0;
	rep(i,s,n){
		if(a[s]==a[i]){
			ans++;
		}
		else break;
	}
	cout<<ans<<endl;
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
	int t;cin>>t;while(t--)
	solve();
	return 0;
}
 
 

B

要求最大子段和,赛时蒟蒻的我居然只想能到线段树的写法(⊙﹏⊙),然后一直卡在第三个测试点过不去,赛后来看是取模都有问题……

补充知识

最大子段和

我们称可能是答案的序列为有效序列,显然有效序列要尽可能地大,所以当前数加有效序列的和大于等于当前数,那么当前数一定在有效序列中,反之,当前数成为新的有效序列,则最大子段和就是有效序列的和的最大值

模拟一下这个过程:
如2 -4 3 -1 2 -4 3
有效序列初始只有第一个数2,为{2}考虑第二个数-4,加上有效序列的和后和为-2,比-4大,有效序列为{2,-4},
考虑第三个数3,加上有效序列的和后和为1,比3小,则更新有效序列为{3},
以此类推,所有有效序列为{2},{2,-4},{3},{3,-1},{3,-1,2},{3,-1,2,-4},{3};
所以ans就为这些有效序列的和的最大值
	int n;cin>>n;
	rep(i,1,n) cin>>a[i];
	int res=a[1],ans=-1e9;
	rep(i,2,n){
		res=max(a[i]+res,a[i]);
		ans=max(res,ans);
	}
	cout<<ans;

分析

因为可以在任意位置插入了该子数组的和,我们可以选择子段和最大的,和为sum,将其插入该子数组旁边,这样新的最大子段和就为sum乘2,以此类推,若还能插入,则新的最大子段和依次为sum乘4、_sum乘8、_sum乘16……而除了子段和最大的序列外的部分没有变化,所以ans=初始数组和-sum+sum*2^k;

操作

思路想通后,主要就是取模的问题:有求和操作的要取模,有乘法运算的要取模后再相乘有相减运算的要加上模数再取模,求最值则不用取模

代码

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define db(x) cout<<x<<" "<<endl;
#define _db(a,n) for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl;
#define mem(a) memset(a,0, sizeof(a))
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
#define lc p<<1
#define rc p<<1|1//可见当时自己有多若只
const int mod=1e9+7;
const int N=2e5+5;
int n,a[N];
int fp(int b,int p){
	int res=1;
	while(p){
		if(p&1) res=res*b%mod;
		b=b*b%mod;
		p>>=1;
	}
	return res;
}
void solve(){
	int k,sumv=0,cs=0,f=1;cin>>n>>k;
	rep(i,1,n){
		cin>>a[i];
		sumv+=a[i];
		sumv%=mod;
	}
	int res=a[1],sum=max(a[1],0ll);//0ll就是0
	rep(i,2,n){
		res=max(a[i]+res,a[i]);
		sum=max(res,sum);
	}
	int ans=((fp(2,k)%mod*(sum%mod))%mod+(sumv+mod-sum)%mod+mod)%mod;//注意(fp(2,k)%mod*sum%mod的写法会爆long long
	cout<<ans<<endl;
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
	int t;cin>>t;while(t--)
	solve();
	return 0;
}

posted @ 2024-03-23 09:43  mono_4  阅读(7)  评论(0编辑  收藏  举报