[HDU 4569] Special equations (数学+技巧+脑洞)

来源:互联网 发布:网络短信在线发送 编辑:程序博客网 时间:2024/04/28 15:55

HDU - 4569
给你一个多项式,求使得多项式 mod (P*P)的平方为 0的解

刚开始题目扯了一堆 CRT啥啥啥的,其实是烟雾弹
注意到这题 P只有 1e4,意味着可以从 0..P-1 枚举出 x的解
因为根据 mod 的性质,以及 f(x)是多项式
如果 f(x)%P=0,那么 f(x+P)%P=0
所以只需要枚举 0..P-1就好了
但是这题求的是 mod P*P就比较麻烦,乘起来是 1e8,不可能枚举
所以意味着上面说的方法不行……

然而真的不行吗,看了下题解,正解就是这个……
实际上,如果 mod P*P为 0,那么首先 mod P要为 0
如果 f(x) mod P为 0的情况下,再去枚举 x+k*P 到 P*P
这样看起来还是会 T,但实际上解是比较稀疏的
所以 mod P的判定可以剪掉很多,而最终不会 T

艺高人胆大啊,是在下输了……
以后碰到不会的题,还是先别急着 GG
没准就是个玄学复杂度的暴力呢 orz
好像关于因子和模的题,玄学复杂度的还真不少

#include <cstdio>#include <iostream>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <map>#include <set>#include <queue>using namespace std;typedef pair<int,int> Pii;typedef long long LL;typedef unsigned long long ULL;#define MST(a,b) memset(a,b,sizeof(a))#define CLR(a) MST(a,0)#define Pow2(a) (a*a)int deg;LL a[5],P;bool func(LL x, LL mod){    LL res=0,now=1;    for(int i=0; i<=deg; i++)    {        res=(res+now*a[i])%mod;        now=(now*x)%mod;    }    if(res%mod) return 0;    return 1;}int main(){    int T;    scanf("%d", &T);    for(int ck=1; ck<=T; ck++)    {        scanf("%d", &deg);        for(int i=deg; i>=0; i--) scanf("%lld", &a[i]);        scanf("%lld", &P);        LL ans=-1;        for(LL i=0; i<P; i++)        {            if(!func(i,P)) continue;            for(LL j=i; j<=P*P; j+=P)            {                if(!func(j,P*P)) continue;                ans=j;                goto END;            }        }        END:;        printf("Case #%d: ", ck);        if(~ans) printf("%lld\n", ans);        else puts("No solution!");    }    return 0;}
0 0
原创粉丝点击