小朋友的数字
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 typedef long long ll; 8 const ll maxn=1e6+7; 9 const ll INF=0x7f7f7f7f; 10 ll n,p,imax,ans=-INF,da=-INF,xiao,imx=-INF; 11 ll a[maxn],b[maxn],c[maxn],sum[maxn],imin[maxn]; 12 int main(){ 13 cin>>n>>p; 14 for(ll i=1;i<=n;i++) cin>>a[i]; 15 for(ll i=1;i<=n;i++){ 16 sum[i]=sum[i-1]+a[i]; 17 } 18 /*for(ll i=1;i<=n;i++){ 19 if(sum[i]-xiao>da){ 20 da=sum[i]-xiao;b[i]=da; 21 } 22 else{ 23 b[i]=da; 24 xiao=min(xiao,sum[i]); 25 } 26 }*/ 27 for(int i=1;i<=n;i++){ 28 sum[i]=max(sum[i-1]+a[i],a[i]); 29 imx=max(sum[i],imx); 30 b[i]=imx%p; 31 } 32 ans=c[1]=b[1];imax=b[1]+c[1]; 33 for(ll i=2;i<=n;i++){ 34 c[i]=imax; 35 if(ans<c[i]) ans=c[i]%p;//* 36 imax=max(imax,c[i]+b[i]); 37 } 38 if(ans<0) cout<<-abs(ans)%p<<endl; 39 else cout<<ans%p<<endl; 40 }
求最大连续子段和,注释掉的那段如果在20行的时候更新一下xiao就是对的了
有*的那一句,ans=max(ans,c[i]%p)就是不对的,因为ans比较的是c[i],只是最后答案对p取模,中间如果直接取模的话,会影响大小的比较
还有一种高精度,避免了取模的细节,可以用两个long long 拼起来
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const ll maxn=1e6+7; const ll base=1e9; const ll INF=0x7f7f7f7f; struct pii{ ll high,low; friend inline pii operator + (const pii &a,const pii &b){ pii c;c.high=a.high+b.high;c.low=a.low+b.low; if(c.high>=0&&c.low>=base){ c.high+=c.low/base;c.low%=base; } if(c.high<=0&&c.low<=-base){ c.high+=c.low/base;c.low%=base; } if(c.high>0&&c.low<0){ c.high--;c.low+=base; } if(c.high<0&&c.low>=base){ c.high++;c.low-=base; } return c; } friend inline bool operator<(const pii &a,const pii &b){ if(a.high==b.high) return a.low<b.low; else return a.high<b.high; } friend inline pii max(const pii &a,const pii &b){ if(a<b) return b; else return a; } }; ll n,p; pii a[maxn],b[maxn],c[maxn],sum[maxn],imx,imax,ans,da; int main(){ cin>>n>>p; for(int i=1;i<=n;i++) cin>>a[i].low; b[1]=a[1]; for(int i=2;i<=n;i++){ sum[i]=max(sum[i-1]+a[i],a[i]); b[i]=max(b[i-1],sum[i]); } ans=b[1]=sum[1]=c[1]=a[1]; for(int i=2;i<=n;i++){ sum[i]=max(sum[i-1]+a[i],a[i]); b[i]=max(sum[i],b[i-1]); if(i==2) c[i]=c[1]+b[1]; else c[i]=max(c[i-1]+b[i-1],c[i-1]); ans=max(ans,c[i]); } cout<<(((ans.high%p)*base)%p+ans.low%p)%p<<endl; }