CF1845D 题解

又是切题的一天。

这道题,一看到,就知道应该先用一个前缀和。

不难知道,最大值所对应的 k k k 一定是 前缀和数组 p r e pre pre 中的一个数。

用一个变量 m x i mx_i mxi 记录 p r e 1 , p r e 2 , … , p r e i pre_1,pre_2,\dots,pre_i pre1,pre2,,prei 中的最大值,则 x i x_i xi m x i + p r e n − p r e i mx_i+pre_n-pre_i mxi+prenprei(即 p r e 1 , p r e 2 , … , p r e i pre_1,pre_2,\dots,pre_i pre1,pre2,,prei 中的最大值加上后面的数之和)。

枚举每一个 i i i,不断更新最大值,结果就是使 x x x 最大的 m x mx mx 了。

my code:

#include <bits/stdc++.h>
#define int __int128
using namespace std;
namespace FIO{
	#define MP make_pair
	#define F first
	#define S second
	#define R register
	#define I inline
	#define Pii pair<int,int>
	#define D isdigit
	#define A isalpha
	#define MS memset
	#define SO sizeof
	double fpow(double a,int n){
		double ans=1;
		while(n){
			if(n&1) ans*=a;
			a*=a;
			n>>=1;
		}
		return ans;
	}
	void readI(int &x){
		x=0;
		int f=1,c=getchar();
		while(!D(c)){
			if(c=='-') f=-1;
			c=getchar();
		}
		while(D(c)){
			x=(x<<1)+(x<<3)+(c^48);
			c=getchar();
		}
		x=f*x;
	}
	void put(int x){
		if(x<0){
			putchar('-');
			put(-x);
			return ;
		}
		if(x>=10) put(x/10);
		putchar(x%10+48);
	}
	void writeI(int x,char end){
		put(x);
		putchar(end);
	}
	int readS1(char*&s){
		memset(s,0,sizeof s);
		int c=getchar(),len=0;
		while(c==' '||c=='\n') c=getchar();
		while(c!=' '&&c!='\n'){
			s[len++]=c;
			c=getchar();
		}
		return len;
	}
	void writeS1(char*s,char end){
		int len=strlen(s);
		for(int i=0;i<len;i++) putchar(s[i]);
		putchar(end);
	}
	int readS2(string &s){
		s="";
		int c=getchar(),len=0;
		while(c==' '||c=='\n') c=getchar();
		while(c!=' '&&c!='\n'){
			s+=c;
			len++;
			c=getchar();
		}
		return len;
	}
	void writeS2(string s,char end){
		int len=s.size();
		for(int i=0;i<len;i++) putchar(s[i]);
		putchar(end);
	}
	void readC(char &c){
		c=getchar();
	}
	void writeC(char &c){
		putchar(c);
	}
	void readD(double &d){
		int x=0,f=1,c=getchar(),len=-1;
		double y=0;
		while((!D(c))&&(c!='.')){
			if(c=='-') f=-1;
			c=getchar();
		}
		while(D(c)||c=='.'){
			if(c=='.') len=0;
			else{
				if(len==-1) x=(x<<1)+(x<<3)+(c^48);
				else y+=(c^48)*fpow(0.1,++len);
			}
			c=getchar();
		}
		d=(x+y)*f;
	}
	void writeD(double d,int len,char end){
		int x=d;
		double y=d-x;
		put(x);
		if(abs(y)>1e-6) putchar('.');
		while(abs(y)>1e-6&&len--){
			int k=y*10;
			putchar(k+48);
			y=y*10-k;
		}
		while(len>0) len--,putchar('0');
	}
}
using namespace FIO;
const int N=3e5+20;
int t,n,a[N],pre[N],mx,ans,ansk;
I void solve(){
	readI(n);
	for(int i=1;i<=n;i++) readI(a[i]),pre[i]=pre[i-1]+a[i];
	mx=ans=ansk=0;
	for(int i=1;i<=n;i++){
		mx=max(mx,pre[i]);
		if(ans<mx+pre[n]-pre[i]){
			ans=mx+pre[n]-pre[i];
			ansk=mx;
		}
	}
	writeI(ansk,'\n');
}
signed main(){
	readI(t);
	while(t--) solve();
	return 0;
}



彩蛋

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值