HDU_4379_The More The Better

来源:互联网 发布:欧姆龙编程软件cx one 编辑:程序博客网 时间:2024/06/04 08:03

题意:

       一个长度为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;}



0 0