社区讨论

求助,洛谷AC,但是 Atcoder WA

P3306[SDOI2013] 随机数生成器参与者 3已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@lo7y9rd5
此快照首次捕获于
2023/10/27 09:44
2 年前
此快照最后确认于
2023/10/27 09:44
2 年前
查看原帖
明明洛谷可以过,但是在 Atcoder WA 掉力。。。。求助帮忙 de 一下 BSGS!!!
顺便问一下,我根据题解一篇关于矩阵的方法写的,但是我没有用到逆元,为什么还需要特判?
CPP
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll p;
struct matrix
{
    static const ll HASH = 13331;
    static const ll mod = 1e9+7;
    ll a[2][2];
    matrix() {memset(a, 0, sizeof(a));}
    ll* operator[](int x) {return a[x];}
    friend matrix operator*(matrix a, matrix b)
    {
        matrix c;
        c[0][0]=(a[0][0]*b[0][0]+a[0][1]*b[1][0])%p;
        c[0][1]=(a[0][0]*b[0][1]+a[0][1]*b[1][1])%p;
        c[1][0]=(a[1][0]*b[0][0]+a[1][1]*b[1][0])%p;
        c[1][1]=(a[1][0]*b[0][1]+a[1][1]*b[1][1])%p;
        return c;
    }
    ll getHash()
    {
        ll h=0;
        h=(h*HASH+a[0][0])%mod;
        h=(h*HASH+a[0][1])%mod;
        h=(h*HASH+a[1][0])%mod;
        h=(h*HASH+a[1][1])%mod;
        return h;
    }
};

ll a,b,x,t;
matrix e;

matrix qpow(matrix a, ll b)
{
    matrix ans=e;
    for(; b; b>>=1,a=a*a)
    if(b&1) ans=ans*a;
    return ans;
}
ll BSGS(matrix a, matrix b, matrix c)
{
    unordered_map<ll,ll> mp;
    ll sq=sqrt(p)+1;
    matrix s=qpow(a, sq),now=b;

    for(ll i=0; i<sq; i++)
    {
        ll h=(c*qpow(a, i)).getHash();
        if(!mp.count(h)) mp[h]=i;
    }

    for(ll i=0; i<=sq; i++)
    {
        if(mp.count(now.getHash())&&i*sq-mp[now.getHash()]>=0)
        return i*sq-mp[now.getHash()]+1;
        now=now*s;
    }
    return -1;
}
void work()
{
    matrix A,B,C;
    scanf("%lld%lld%lld%lld%lld", &p, &a, &b, &x, &t);
    A[0][0]=a; A[0][1]=0; A[1][0]=b; A[1][1]=1;
    B[0][0]=x; B[0][1]=1; C[0][0]=t; C[0][1]=1;
    if(!a)
    {
        if(t==x) puts("1");
        else if(t==b) puts("2");
        else puts("-1");
    }
    else
    {
        matrix A,B,C;
        A[0][0]=a; A[0][1]=0; A[1][0]=b; A[1][1]=1;
        B[0][0]=x; B[0][1]=1; C[0][0]=t; C[0][1]=1;
        printf("%lld\n", BSGS(A, B, C));
    }
}
int main()
{
    e[0][0]=e[1][1]=1;
    int t;
    cin>>t;
    while(t-->0)
    work();
    return 0;
}

回复

8 条回复,欢迎继续交流。

正在加载回复...