BZOJ3613 HEOI2014南园满地堆轻絮
不明白在某谷上是怎么标到紫的。二分答案或者发现答案就是最大逆序差的一半。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 5000010 int n,a[N],P,w,x,y,z; int f(int t){return ((1ll*w*t%P*t%P*t%P+1ll*x*t%P*t%P)%P+(1ll*y*t%P+z)%P)%P;} bool check(int x) { int last=0; for (int i=1;i<=n;i++) if (a[i]>=last) last=max(last,a[i]-x); else if (last-a[i]>x) return 0; return 1; } int main() { #ifndef ONLINE_JUDGE freopen("bzoj3613.in","r",stdin); freopen("bzoj3613.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(),w=read(),x=read(),y=read(),z=read(),a[1]=read(),P=read(); for (int i=2;i<=n;i++) a[i]=(f(a[i-1])+f(a[i-2]))%P; int l=0,r=P,ans=0; while (l<=r) { int mid=l+r>>1; if (check(mid)) ans=mid,r=mid-1; else l=mid+1; } cout<<ans; return 0; }