可做题2(Code+12月网络赛)(扩欧+矩阵快速幂)

来源:互联网 发布:ubuntu软件库打不开 编辑:程序博客网 时间:2024/06/07 07:14

题目背景

“codeplus比赛的时候在做什么?有没有空?能来解决丢番图方程问题吗?”sublinekelzrip这样问qmqmqm。

当然,qmqmqm并不会丢番图方程问题,所以sublinekelzrip改为提出了另一个题目,现在请你帮助qmqmqm解决这个题目。

题目描述

这个问题是这样的:

若一个数列a满足条件an=an1+an2,n>3,a1,a2为任意实数,则我们称这个数列为广义斐波那契数列。

现在请你求出满足条件a1=ia2为区间[l,r]中的整数,且akmodp=m的广义斐波那契数列有多少个。

输入格式

从标准输入读入数据。

本题包含多组数据,输入第一行包含一个正整数T,表示数据组数。对于每组数据:

一行六个用空格隔开的整数i,l,r,k,p,m,意义如题目描述所示。

输出格式

输出到标准输出。

输出共T行,每行一个数表示该组数据的答案。

样例1输入

62 17 68 3 23 11 17 68 3 57 15 17 68 10 11 95 17 68 10 71 910 17 68 11 12 310 17 68 8 6 4

样例1输出

314159

子任务

测试点kr其他1100100无2105105341018561051018p为质数7810189无10

对于所有数据,0lr,1p109,T=10,0i1018,k3


题解:

算法一

暴力枚举所有可能的a2并递推判断。
复杂度O(r×k),预期得分10分。

算法二

ak可以表示为a1a2的线性组合。
使用递推计算出系数,并暴力枚举所有可能的a2判断。
复杂度O(r+k),预期得分30分。

算法三

暴力枚举所有可能的a2并使用矩阵乘法判断。
复杂度O(r×log(k)),预期得分50分。

算法四

与算法二类似,使用递推计算出系数,此时可以发现可能的a2满足一个同余方程,使用扩展欧几里得或逆元求解即可。
可以通过测试点6,7。

算法五

将算法四中计算系数的方式改为矩阵乘法,可以通过测试点8。

算法六

由于p可能不是质数,所以需要判断不互质的情况,然后使用扩展欧几里得或欧拉定理求解同余方程。可以通过所有数据。

考场上果断算法三
后来虚泽口hu出了正解

如果知道了首项和第二项
我们就可以用矩阵快速幂求出第k项

相当于我们已知a[k]%p,a[1],fib(k-2),fib(k-1)
令a=fib(k-1),b=m-i*fib(k-2),x=a[2],

则方程转化为:a*x ≡ b(%p),求解x=[l,r]的整数解

运用exgcd求解过程:

  • 转化为不定方程:ax-py=b
  • g=gcd(a,p),若b%p≠0则无解(输出0)
  • a/=g,p/=g,b/=g
  • 求解a’x-p’y=1即exgcd(a,p)
  • 得到最小非负整数解x=x*b(如果x<0,我们需要通过+p%p处理一下)
  • 计算在[l,r]之间的解:cal(r,x)-cal(l-1,x)
ll cal(ll r,ll x){    if (r<x) return 0;    return (r-x)/p+1;    //每隔p个就有一解}

tip

i读入的时候就需要%p

在solve的时候:p —> p/gcd(a,p)

不知道这是什么鬼畜原理,
可能是因为求解是建立在:ax+py=gcd(a,p) 的基础上
之后的解也是每隔p/gcd(a,p)就有一个

//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;ll p;struct node{    ll H[3][3];    node operator *(const node &a) const     {        node ans;        for (int i=1;i<=2;i++)            for (int j=1;j<=2;j++){                ans.H[i][j]=0;                for (int k=1;k<=2;k++)                    ans.H[i][j]=(ans.H[i][j]+H[i][k]*a.H[k][j])%p;        }        return ans;    }    void clear()    {        memset(H,0,sizeof(H));    }    node KSM(ll p)    {        node ans=(* this);        node a=(* this);        p--;        while (p)        {            if (p&1) ans=ans*a;            p>>=1;            a=a*a;        }        return ans;    }};node H;ll i,l,r,k,m,x,y;ll gcd(ll a,ll b){    ll r=a%b;    while (r)    {        a=b; b=r;        r=a%b;    }    return b;}void exgcd(ll a,ll b){    if (b==0)    {        x=1; y=0;        return;    }    exgcd(b,a%b);    ll t=x;    x=y;    y=t-a/b*y;}ll cal(ll r,ll x){    if (r<x) return 0;    return (r-x)/p+1;}ll solve(ll a,ll b){    ll c=gcd(a,p);    if (b%c!=0) return 0;    a/=c; b/=c; p/=c;               //p/=c    exgcd(a,p);    x=(x*b+p)%p;                    //解     while (x<0) x=(x+p)%p;    return (ll)(cal(r,x)-cal(l-1,x));}int main(){    H.H[1][1]=1; H.H[1][2]=1;    H.H[2][1]=1; H.H[2][2]=0;    int T;    scanf("%d",&T);    while (T--)    {        scanf("%lld%lld%lld%lld%lld%lld",&i,&l,&r,&k,&p,&m);        i%=p;        node ans=H.KSM(k-2);        ll f1=ans.H[1][1]%p;               //fib(k-1)         ll f2=((m-ans.H[2][1]%p*i%p)%p+p)%p;   //fib(k-2)        //f1*x ≡f2(%p)        printf("%lld\n",solve(f1,f2));    }    return 0;} 
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 南方全球基金净值 大成创新基金净值 华夏复兴基金净值 银华优选基金净值 广发聚丰基金净值查询 银河银泰基金净值 诺安平衡基金净值 大成蓝筹稳健基金净值 天天基金网每日净值 博时主题行业基金净值 华安策略优选基金净值 南方全球精选基金净值 长城安心回报基金净值 002001华夏回报净值 华夏全球精选基金净值 银华内需精选基金净值 博时新兴成长基金净值 南方绩优成长基金净值 260109基金今天净值 汇添富均衡基金净值 天天基金网每日净值查询 南方成份精选基金净值 华宝行业精选基金净值 200008长城品牌净值 广发稳健增长基金净值 中国基金网每日净值 净化大师 血液净化 莱恩的净化 净化 净化少女 空气净化 净化除味 净化空气 水净化 净化心灵 水的净化 净化之眼 魔兽净化 水净化项目 净化水