HDU_4379_The More The Better

本文分享了一道关于寻找特定子序列的算法题的解决过程。通过对原始算法的不断优化,包括使用合适的数据类型、避免使用某些标准库函数等手段,在限定的时间内成功解决了难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值