小朋友的数字

 

 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;
} 

 

posted @ 2018-11-04 09:01  lcan  阅读(338)  评论(0编辑  收藏  举报