题意:
一个长度为n的序列X,Xk = (a*k+b)%mod,找出一个最长的子序列{Y},使得任意两个元素之和都不大于L,求出子序列的长度。
分析:
这是我做过的最卡的题,时间卡到不行。
时限是2000MS,n的范围是2*10^7,想了一个O(n)的方法,还脑残的把X序列全存数组里了,交了一发MLE。
然后发现根本不需要存(蠢哭)。
算法是木有错的,比L/2小的都算,然后如果比L/2大的里面最小的加上比L/2小的里面最大的也满足条件的话,再加上一个。
可能是常数大了的缘故,写完代码,若干次尝试,修改为如下地方后,终于卡过,都要哭了。。。
(1)全用__int64
(2)计算Xi的时候要强制转换(完全搞不懂状况)
(3)不用min()和max()函数
(4)头文件删的只剩stdio.h,没错,是stdio.h,不是cstdio。(妈蛋)
代码:
#include<stdio.h>
int main() {
__int64 i,n,l,a,b,mod,mid,ans,maxn,minn,x;
while(~scanf("%I64d%I64d%I64d%I64d%I64d",&n,&l,&a,&b,&mod)) {
mid = l / 2;
ans = 0;
maxn = -1;
minn = 9999999999999LL;
for(i=1; i<=n; i++) {
x=((__int64)((__int64)a*i+b)%mod);
if(x <= mid) {
ans ++;
if(maxn<x) maxn=x;
} else {
if(minn>x) minn=x;
}
}
if(maxn+minn <= l) ans++;
printf("%I64d\n",ans);
}
return 0;
}