这道题可以转化为Hash+差分序列模型,但我所要说的是在常数上的优化。
考虑转化为差分序列时,我们在其左端点加上Y-X,在右端点的下一位加上Z-Y;并且对于所有牛都是一样的。所以我们交换两个牛的右端点,对答案不会有任何影响。那么我们干脆就把左右端点分开来考虑好了。
有什么好处?
考虑普通的hash,需要先排序再二分≈T(4Nlog(2N)+9N);而根据上述思想,我们完全可以做到排序+线性扫描≈T(2NlogN+7N),可以大大削减常数。
写的时候犯了一些错误:
①把Y当Z使了。。
②没有把右端点+1
③没有处理边界。
④用一个变量表示好多意思的时候,没有分清其在某个时刻的意义到底是什么。
#include<iostream> using namespace std; #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> int A[20001],B[20001]; char * ptr=(char *)malloc(300000); inline void in(int &x){ while(*ptr<'0'||*ptr>'9')++ptr; x=0; while(*ptr>47&&*ptr<58)x=x*10+*ptr++-'0'; } int main(){ freopen("milktemp.in","r",stdin);freopen("milktemp.out","w",stdout); int N,X,Y,Z,i; fread(ptr,1,300000,stdin); in(N),in(X),in(Y),in(Z); for(i=N;i;--i)in(A[i]),in(B[i]),++B[i]; A[0]=A[N],B[0]=B[N]; sort(A,A+N),sort(B,B+N); int now=X*N,ans=max(now,Z*N),j=0,k; Z=Z-Y,Y=Y-X,i=0; A[N]=-1,B[N]=-1; while(i<N&&j<N){ k=min(A[i],B[j]); while(A[i]==k)now+=Y,++i; while(B[j]==k)now+=Z,++j; ans=max(ans,now); } printf("%d",ans); return 0; }
①寻找题目中的等价关系往往能给我们一些优化。
②处理边界的时候一定要头脑清晰。