【題解】[牛客網NOIP賽前集訓營-提高組(第二場)]B.分糖果 單調棧優化線性DP+容斥原理
阿新 • • 發佈:2018-11-01
#include<cstdio> #define re register typedef long long ll; const int N=1e6+10; const int INF=0x3f3f3f3f; const int mod=1e9+7; template<typename tp>inline int getmin(tp&x,tp y){return y<x?x=y,1:0;} template<typename tp>inline int getmax(tp&x,tp y){return y>x?x=y,1:0;} template<typename tp>inline void read(tp&x) { x=0;re int f=0;re char ch=getchar(); while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar(); while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); if(f)x=-x; } template<typename tp>inline void write(tp x) { re int buf[40],p=0; if(x<0)putchar('-'),x=-x; do{ buf[p++]=x%10;x/=10; }while(x); for(re int i=p-1;i+1;i--)putchar(buf[i]+48); putchar('\n'); } template<typename tp>inline int add(tp x,tp y){return x+y>=mod?x+y-mod:x+y;} template<typename tp>inline int dec(tp x,tp y){return x-y<0?x-y+mod:x-y;} template<typename tp>inline int mul(tp x,tp y){return 1ll*x*y%mod;} int n,mn=INF,a[N],pos,b[N],sta[N],val[N],f[N],sum,top; int main() { //freopen("in.txt","r",stdin); read(n); for(re int i=1;i<=n;i++) { read(a[i]); if(getmin(mn,a[i]))pos=i; } for(re int i=1;i<=n;i++) b[i]=a[(pos+i-2)%n+1]; sta[++top]=1;val[1]=b[1];f[1]=b[1]; for(re int i=2;i<=n;i++) { sta[++top]=i;val[i]=f[i-1]; while(top>1&&b[sta[top-1]]>b[sta[top]]) { if((i-sta[top-1])&1) { val[i]=dec(val[i],val[sta[top-1]]); sum=dec(sum,mul(b[sta[top-1]],val[sta[top-1]])); } else { val[i]=add(val[i],val[sta[top-1]]); sum=add(sum,mul(b[sta[top-1]],val[sta[top-1]])); } sta[top-1]=sta[top];top--; } sum=dec(mul(b[i],val[i]),sum); if(i&1)f[i]=add(sum,f[1]); else f[i]=dec(sum,f[1]); } for(re int i=top;i>1;i--) { if((n-sta[i])&1)f[n]=add(f[n],val[sta[i]]); else f[n]=dec(f[n],val[sta[i]]); } f[n]=(n&1?dec(f[n],f[1]):add(f[n],f[1])); write(f[n]);return 0; }
總結
容斥原理結合單調棧DP好題