羅区P4774 [NOI2018] Tulong龍市

効果の件名:

この質問と表面データ範囲は非常に良いスティックではない、自分の目で確かめてください......

まず、我々はこれがあることを確認することができるはずです\(excrt \)タイトル

この制限は非常に剣であるとして、\(\ナイーブ)とを、\(マルチセット\)だけで罰金を存在

問題の意味によると、私たちは方程式を一覧表示することができます

\ [\開始{ケース} d_1x \当A_1(MOD \ P_1)\\ d_2x \当A_2(MOD \ P_2)\\ ...... \\ d_nx \当A_N(MOD \ P_N)\端{ケース} \]

どこに\(D_I \) 剣の攻撃である(X- \)\、攻撃の数として(a_iを\)\、曇った血液として(P_I \)\返信する機能です

しかし、我々は持っているように見える\(a_iを> P_I \)私たちが直接出て成形するように見えることはできません対象に応じて......ケースを......

しかし、我々ターンの後、問題の解決策そこにできることが分かっ\(a_iを> P_I \) すべてを満たす\(P_I = 1 \)そして、私たちは強くうまくアウト決定します

具体的な方法:

\ [ANS = maxの\ {\ lceil \ FRAC {D_I} {a_iを} \ rceil \} \]

一般的なソリューション

考えてみましょう\(d_ix \当量a_iを(MOD \ P_I)\) など、および一般\(CRTが\)それを簡素化し、同じ式ではありません

\ [X * D_I + Y * P_I = - a_iを\]

(exgcd \)\のセットを取得するために\(X_T、y_t \)

ための\(ecgcd \)一般解\(X = X_T + K * \ FRAC {B} {GCD(A、B)} \) 精製し(X = X_T + K * \ \ FRAC {P_I} {GCD(P_I 、D_I)} \)

以下のための\(\ FRAC {P_I} { GCD(P_I、D_I)} \) モジュロギブ

\(X \当X_T(MOD \ \ FRAC {P_I} {GCD(P_I、D_I)})\)

その後、精力的に\(excrt \)

ご注意ください

私たちは、感性を引き出すことができる方法を理解する(\ X- \ GE(MAXN =最大\ {\ lceil \ FRAC D_I} {} {a_iを\ rceil \}))\最後の答えは少ない。この数を超える場合、構成する必要があります

我々はに導入されている\(RET = RET + M * \ lceil \ FRAC {MAXN-RET} {M} \ rceil \)

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
#define eps (1e-8)
    inline int read()
    {
        int x=0;char ch,f=1;
        for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
        if(ch=='-') f=0,ch=getchar();
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    const int N=1e5+10;
    int haku;
    int n,m;
    int a[N],p[N],sword[N];
    inline void exgcd(int &x,int &y,int &g,int a,int b)
    {
        if(!b){x=1,y=0,g=a;return;}
        exgcd(y,x,g,b,a%b);
        y-=a/b*x;
    }
    inline int slow(int x,int k,int p)
    {
        int ret=0;
        while(k)
        {
            if(k&1) ret=(ret+x)%p;
            x=(x+x)%p;
            k>>=1;
        }
        return ret;
    }
    multiset<int> q;
    multiset<int>::iterator it;
    inline int excrt()
    {
        int m=1,ret=0,maxn=0,x,y,g;
        for(int i=1;i<=n;++i)
        {
            it=q.upper_bound(a[i]);
            if(it!=q.begin()) --it;
            int k=*it;
            q.erase(it);
            q.insert(sword[i]);
            maxn=max(maxn,(a[i]-1)/k+1);
            k%=p[i],a[i]%=p[i];
            exgcd(x,y,g,k,p[i]);
            if(a[i]%g) return -1;
            p[i]/=g;
            a[i]=slow(a[i]/g,(x%p[i]+p[i])%p[i],p[i]);
            int c=((a[i]-ret)%p[i]+p[i])%p[i];
            exgcd(x,y,g,m,p[i]);
            if(c%g) return -1;
            x=slow(x,c/g,p[i]);
            ret+=x*m;
            m*=p[i]/g;
            ret%=m;
        }
        return ret>=maxn?ret:ret+m*((maxn-ret-1)/m+1);
    }
    inline void main()
    {
        haku=read();
        while(haku--)
        {
            n=read(),m=read();
            for(int i=1;i<=n;++i) a[i]=read();
            for(int i=1;i<=n;++i) p[i]=read();
            for(int i=1;i<=n;++i) sword[i]=read();
            for(int i=1;i<=m;++i) q.insert(read());
            printf("%lld\n",excrt());
            q.clear();
        }
    }
}
signed main()
{
    red::main();
    return 0;
}

おすすめ

転載: www.cnblogs.com/knife-rose/p/12058420.html