题意:
思路:看一下这个函数f(x),不难发现它是一条开口向下的抛物线,在[a,b]这个范围f(x)>0,所以要求S(n)-S(m)的最大值,即求区间[a,b]这一部分的累加和,即S(n)-S(m)=S(b)-S(a),我们来列出式子,S(n)-S(m)=-(m-a)(m-b)-(m+1-a)(m+1-b)-...-(n-a)(n-b)=-(m^2-(a+b)m+ab)-((m+1)^2-(a+b)(m+1)+ab)-...-(n^2-(a+b)n+ab)=-(m^2+(m+1)^2+...+n^2)-(a+b)(m+(m+1)+..n)-(ab+ab+..+ab)。
公式:1^2+2^2+..+n^2=n(n+1)(2n+1)/6。
所以,m^2+(m+1)^2+...+n^2=n(n+1)(2n+1)/6-(m-1)m(2m-1)/6。
等差公式,m+(m+1)+..n=(m+n)/2*(n-m+1)。
注意:这道题还是有挺多坑的,一个是数据范围,还有一个是取模运算哪里,负数要记得+mod,再取模!!!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod= 998244353;
ll t,a,b;
ll qmi(ll a,ll k)
{
ll res=1;
while(k)
{
if(k&1) res=res*a%mod;
a=a*a%mod;
k>>=1;
}
return res;
}
int main()
{
cin>>t;
while(t--)
{
cin>>a>>b;
ll n=b,m=a;
ll res=0;
ll s1=-(n*(n+1)%mod*(2*n+1)%mod*qmi(6,mod-2)%mod-m*(m-1)%mod*(2*m-1)%mod*qmi(6,mod-2)%mod+mod)%mod;
ll s2=(a+b)*(m+n)%mod*qmi(2,mod-2)%mod*(n-m+1)%mod;
ll s3=-(a*b%mod*(n-m+1)%mod);
cout<<((s1+s2+mod)%mod+s3+mod)%mod<<"\n";
}
return 0;
}
E 禅
题意:
思路:从终点往两个方向走, f[i]以i为起点走到终点的需要的最小初始值
f[i]=f[i+1]-a[i],因为如果能够经过这个点,那么肯定就要加上这个点的值,所以f[i]=f[i+1]-a[i]
同理向另外一边也是,f[i]=f[i-1]-a[i]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10,INF=0x3f3f3f3f;
int a[N],f[N];
int t,n;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int idx;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
//f[i]=0;
if(a[i]==0) idx=i;
}
if(n==1)
{
printf("No Solution\n");
continue;
}
f[idx]=0;
int ans=INF;
for(int i=idx-1;i>0;i--)
{
f[i]=max(f[i+1]-a[i],a[i]+1);
ans=min(ans,f[i]);
}
for(int i=idx+1;i<=n;i++)
{
f[i]=max(f[i-1]-a[i],a[i]+1);
ans=min(f[i],ans);
}
printf("%d\n",ans);
}
return 0;
}