2019년 9월 15일 - 단행본 코스 요약의 수 (DAY2)

\ (xgzc, QwQ \) ~~~~~~

\ (PartA : GCD \)

대답 입증 된 특정 아이디어의 양 및이를 모르는 후 은퇴유클리드 수학의 행방그것은 ......

inline int gcd(int a,int b)
{
    return !b?a:gcd(b,a%b);
}

\ (확대 : exgcd의 \)

하지, 그것을 허용하지 않습니다 이마, (전년 동기 대비 \) \ 그것 ~ ~ 나온 것을
필요 해결의 가능성과 충분 조건 :

\ [= C로 \ 텍스트 {}에서 ~ ~ ~ ~ + 도끼 ~ \ {텍스트 갖는다} ~ ~ ~ GCD (a, b) | C \]

가정 할 \ (AX를 + 의해 = GCD (A, B) \) 가있다 :
\ [AX + 의해 = GCD는 (A는 B) BX ^ { '} + (A ~ MOD ~ B) Y ^ {'= } = GCD (B, A ~
~ B 모드) \] 나 재귀 결합 할 항목을 삭제 :

int x,y;
inline void exgcd(int a,int b)
{
    if(!b)
    {
        x=1,y=0;
        return;
    }
    exgcd(b,a%b);
    int tmp=x;
    x=y;
    y=tmp-a/b*y;
}

틀 : 개구리 날짜 :

#include<bits/stdc++.h>
using namespace std;
#define in(a) a=read()
#define ll long long
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    for(;!isalnum(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
ll jie[2];
inline ll gca(ll s,ll t)
{
    if(t==0) return s;
    return gca(t,s%t);
}
inline void getit(ll s,ll t)
{
    if(t==0)
    {
        jie[0]=1;
        jie[1]=0;
        return;
    }
    getit(t,s%t);
    ll u=jie[1],v=jie[0]-s/t*jie[1];
    jie[0]=u;
    jie[1]=v;
}
int main()
{
    ll n,x,y,a,b;
    in(x);in(y);in(a);in(b);in(n);
    if(a<b) swap(a,b),swap(x,y);
    ll delta=y-x;
    ll q=gca(a-b,n);
    if(delta%q!=0)
    {
        printf("Impossible\n");
        return 0;
    }
    getit(a-b,n);
    ll ans=jie[0]*delta/q;
    ll r=n/q;
    ans=(ans%r+r)%r;
    printf("%lld\n",ans);
    return 0;
}

\ (을 partB : \) 페르마의 작은 정리와 오일러의 정리

페르마의 소정리 :
\ [. A-P ^ {1} \ equiv1 \ ~~~ PMOD {P} (. D_P == 1) \]

오일러의 정리 :
\ [A ^ B의 \의 당량 A를 B ^ {\ % \ 피 (N-)} \ {N-PMOD} \]

\ (부 : BSGS \)

주요 기능은 다음과 같은 수학 식을 해결하기 위해 사용된다 :
\ [A ^ X \ 당량 B \ PMOD {C} \]
PCA 코스 \ (X \) \ (QwQ \) ~~~

이마는, 감 처음 무지 힘에 직면지금도......

자, 이제 내가 언젠가는 철저하게 약간 혼동 할 수 있기를 기대하고, 여전히 곤약 연습 해요 :

주문 \ (m = \ lceil \ SQRT {P} \ rceil, X = 내 + z의 (Y, Z의 \ 텍스트 { } 가변적) \)를 , 다음 경우 \ (a ^ X \ 당량 ㄱ \의 pmod에 {C} \) 설립에있다 \ (A ^ ^ {내} * Z \의 당량 B의 \의 PMOD {C}는 \) , 키 클릭이 이동 \ (a ^ {내} \ 당량 \ FRAC {B} {A ^ Z를 } \ {C} PMOD \) 의 전처리 \에서의 Z \ FORALL \는 (\ 좌측 [1, m의 \ 오른쪽] \) 의 \ (\ FRAC {B} { ^ Z} \) 와 존재 \ (MAP \) 내부 다음 열거 \ (Y의 \) 솔루션이 될 수 있는지를 판단한다.

시간 복잡도 \ (O (\ n 형 SQRT {}) \) :

inline int sol(int a,int b,int c)
{
    if(!(a%c)) return -1;
    int ans=b%c,m=ceil(sqrt(c));
    mp[ans]=0;
    fur(i,1,m)
    {
        ans=ans*a%c;
        mp[ans]=i;
    }
    int tmp=power(a,m,c);ans=1;
    fur(i,1,m)
    {
        ans=ans*tmp%c;
        if(mp[ans]) return (i*m-mp[ans])%c+c)%c;
    }
    return -1;
}

틀 : \ (이산 ~ \ 로깅) :

#include<bits/stdc++.h>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
map <int,int> mp;
inline int power(int x,int k,int mod)
{
    int res=1;
    for(;k;k>>=1,x=x*x%mod) if(k&1) res=res*x%mod;
    return res;
}
inline void sol(int a,int b,int c)
{
    if(!(a%c))
    {
        puts("no solution");
        return;
    }
    int ans=b%c,m=ceil(sqrt(c));
    bool flag=false;
    mp[ans]=0;
    fur(i,1,m)
    {
        ans=ans*a%c;
        mp[ans]=i;
    }
    int tmp=power(a,m,c);ans=1;
    fur(i,1,m)
    {
        ans=ans*tmp%c;
        if(mp[ans])
        {
            printf("%lld\n",((i*m-mp[ans])%c+c)%c);
            flag=true;
            break;
        }
    }
    if(!flag) puts("no solution");
}
jinitaimei main()
{
    int a,b,c;
    while(scanf("%lld%lld%lld",&c,&a,&b)!=EOF)
    {
        mp.clear();
        sol(a,b,c);
    }
    return 0;
}

\ (확장 : exbsgs을 \) (수 소수 아닌 경우) \ (XG \)를 , 그것의 직접 계산 감 비트 종양 인 : [A ^ X \는 B \ PMOD C \를 당량 \ ^ X 향하는 화살표 A = KC + B \] \ [\ 텍스트 {그래서} ~ G = GCD (A, C) \ 희망하므로 \ FRAC {B} {G} \에서 N ^ {*} \] \ [\ RIGHTARROW \ FRAC {A} {G }는 ^ {X-. 1} + K \ FRAC {P} {G} \의 당량의 \의 FRAC {B} {G} \ PMOD {\ FRAC {P} {G}} \] \ [\ RIGHTARROW ^ {X } -1- \ 당량 \ FRAC {B} {G} (\ FRAC {A} {G}) ^ {-.} 1 \ PMOD {\ FRAC {P} {G}} \] \ [\ v ^ {X RIGHTARROW ^ { '}} \의 당량의 B ^ {'} \ pmod에 {m ^ { '}} (X ^ {'} =의 X-1, B ^ { '} = FRAC {B} {g \} (\ FRAC { A} {g}) ^ { - 1}, m은 { '} = \ FRAC는 {P}는 {g}는) \] ^ 유사한 \ (exgcd의 \) 재귀 생각






\ (PartD : CRT의 \)

이것은 합동 방정식을 추구하는 데 사용됩니다 :
\ [\ 케이스 선두 {X} \ 당량 A_1 \ P_1 PMOD {X} \\ \ 당량 A_2 \ {P_2 PMOD ...} \\ \\ X \ 당량 A_N \ PMOD {p_n} \ 끝 {사례}
\] 여기서 \ (P_i는 \) 주요 있습니다

밤 한 군인의 사용이 같은데? ?

아니면 정상 것을 :

(어떤 템플릿 문제는 부호화하지 않도록)
\ [\ 텍스트 {집합} M = 프로드 \의 limits_ \ { I = 1} ^ N p_i, m_i = FRAC {M} {p_i} t_i \ 당량 \ FRAC {\ m_i} {}. 1 \ PMOD P_i {} \]
\ [\하고 텍스트 ANS {} \ 당량 \ 합계 요구 a_it_im_i \ pmod에 {M} \]

\ (연장 : excrt의 \ 텍스트 { ( 많은 단어 QwQ-EX)} \) :

이것은 조금 불편 소수 아니다

스물 두 합병 방정식, 고려 \ (exgcd의 \) 로를 :

const int xx=1e5+1612;
int t[xx],p[xx];
int k1,k2,x,n,M;
inline int gcd(int a,int b){return !b?a:gcd(b,a%b);}
inline void exgcd(int a,int b)
{
    if(!b)
    {
        k1=1,k2=0;
        return;
    }
    exgcd(b,a%b);
    int tmp=k1;
    k1=k2;k2=tmp-a/b*k2;
}
inline int Fast_mul(int a,int b,int mod)
{
    int res=0;
    for(;b;b>>=1,a=(a+a)%mod) if(b&1) res=(res+a)%mod;
    return res;
}
inline void excrt()
{
    M=p[1];x=t[1];
    fur(i,2,n)
    {
        int a=M,b=p[i];
        int c=(t[i]-x%b+b)%b;
        int tmp=gcd(a,b);
        exgcd(a,b);
        int lcm=b/tmp;
        k1=Fast_mul(k1,c/tmp,lcm);
        x+=k1*M;
        M*=lcm;
        x=(x%M+M)%M;
    }
    printf("%lld\n",x);
}

템플릿 :

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
const int xx=1e5+1612;
int t[xx],p[xx];
int k1,k2,x,n,M;
inline int gcd(int a,int b){return !b?a:gcd(b,a%b);}
inline void exgcd(int a,int b)
{
    if(!b)
    {
        k1=1,k2=0;
        return;
    }
    exgcd(b,a%b);
    int tmp=k1;
    k1=k2;k2=tmp-a/b*k2;
}
inline int Fast_mul(int a,int b,int mod)
{
    int res=0;
    for(;b;b>>=1,a=(a+a)%mod) if(b&1) res=(res+a)%mod;
    return res;
}
inline void sol()
{
    M=p[1];x=t[1];
    fur(i,2,n)
    {
        int a=M,b=p[i];
        int c=(t[i]-x%b+b)%b;
        int tmp=gcd(a,b);
        exgcd(a,b);
        int lcm=b/tmp;
        k1=Fast_mul(k1,c/tmp,lcm);
        x+=k1*M;
        M*=lcm;
        x=(x%M+M)%M;
    }
    printf("%lld\n",(x%M+M)%M);
}
inline void init()
{
    n=in;
    fur(i,1,n) p[i]=in,t[i]=in;
}
jinitaimei main()
{
    init();
    sol();
    return 0;
}

Tulong 용시 :

아이디어 매우 흥미로운, 당신은 질문에 이가지 경우 볼 필요 (사용 가능한 \ (excrt의 \) 와 사용할 수 없습니다를하지만, 사용할 필요가 없습니다) 방정식을 단순화, 당신은 템플릿 친구들과 함께 할 수있는 마지막 일을 한 후 열이 많다는 :

#include<bits/stdc++.h>
using namespace std;
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define jinitaimei signed
#define int long long
const int xx=1e5+1612;
int t[xx],p[xx],cnt;
int k1,k2,x,n,M;
int tmp1[xx],tmp2[xx],tmp3[xx],tmp4[xx];
bool flag;
multiset <int> s;
multiset <int>:: iterator it;
inline int gcd(int a,int b){return !b?a:gcd(b,a%b);}
inline void exgcd(int a,int b)
{
    if(!b)
    {
        k1=1,k2=0;
        return;
    }
    exgcd(b,a%b);
    int tmp=k1;
    k1=k2;
    k2=tmp-a/b*k2;
}
inline int Fast_mul(int a,int b,int mod)
{
    int res=0;
    if(b<0) return 1;
    for(;b;b>>=1,a=(a+a)%mod) if(b&1) res=(res+a)%mod;
    return res;
}
inline void sol()
{
    if(flag) return;
    M=p[1];x=t[1];
    fur(i,2,cnt)
    {
        int a=M,b=p[i];
        int c=((t[i]-x%b+b)%b+b)%b;
        int tmp=gcd(a,b);
        exgcd(a,b);
        int lcm=b/tmp;
        if(c%tmp)
        {
            puts("-1");
            return;
        }
        k1=Fast_mul(k1,c/tmp,lcm);
        x+=k1*M;
        M*=lcm;
        x=(x%M+M)%M;
    }
    printf("%lld\n",(x%M+M)%M);
}
inline void init()
{
    s.clear();
    flag=false;cnt=0;
    int tmp=0,m;
    scanf("%lld%lld",&n,&m);
    fur(i,1,n) scanf("%lld",&tmp1[i]);
    fur(i,1,n){scanf("%lld",&tmp2[i]);if(tmp2[i]<tmp1[i]) flag=true;}
    fur(i,1,n) scanf("%lld",&tmp4[i]);
    fur(i,1,m) scanf("%lld",&tmp3[i]);
    fur(i,1,m) s.insert(tmp3[i]);
    fur(i,1,n)
    {
        it=(tmp1[i]<(*s.begin()))?s.begin():(--s.upper_bound(tmp1[i]));
        tmp3[i]=*it;
        s.erase(it);
        s.insert(tmp4[i]);
    }
    if(flag)
    {
        fur(i,1,n) tmp=max(tmp,(int)ceil((double)tmp1[i]/(double)tmp3[i]));
        printf("%lld\n",tmp);
    }
}
inline void handle()
{
    if(flag) return;
    fur(i,1,n)
    {
        if(tmp1[i]==tmp3[i]) continue;
        int tmp=gcd(tmp3[i],tmp2[i]);
        exgcd(tmp3[i],tmp2[i]);
        if(tmp1[i]%tmp)
        {
            puts("-1"),flag=true;
            return;
        }
        k1=Fast_mul(k1,tmp1[i]/tmp,tmp2[i]/tmp);
        t[++cnt]=k1;
        p[cnt]=tmp2[i]/tmp;
    }
}
jinitaimei main()
{
    int T;
    scanf("%lld\n",&T);
    while(T--)
    {
        init();
        handle();
        sol();
    }
    return 0;
}

\ (부 루카스 \)

같은, 당신은 분명히하는 식으로,탈출 ......( \ (P는 \) 은 소수 임) :
\ [C ^ M_n \ 당량 C_ {N - \ %의 P} ^ {m \의 %의 P} * C_ {N- / P} ^ {m / P} \ PMOD {P} \ ]

템플릿 :

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;i++)
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    for(;!isalnum(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
inline ll power(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b>0)
    {
        if(b&1) ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}
ll jc[250000];
inline ll lucas(ll m,ll n,ll mod)
{
    if(m>n) return 0;
    if(m==0) return 1;
    if(m<mod&&n<mod) return jc[n]*power(jc[m]*jc[n-m]%mod,mod-2,mod)%mod;
    return lucas(m/mod,n/mod,mod)*lucas(m%mod,n%mod,mod)%mod;
}
int main()
{
    ll t;t=in;
    while(t--)
    {
        ll n,m,p;
        n=in;m=in;p=in;
        jc[0]=1;
        fur(i,1,n+m) jc[i]=i*jc[i-1]%p;
        printf("%lld\n",lucas(m,n+m,p));
    }
    return 0;
}

\ (확장 : exLucas \) :
이것은 신경 필요 \ (CRT를 \) 식을 만족되도록 화학식 통상 조건 별의 수가

(안 코드에 너무 많은 음식 인난 정말하지 아니에요)

\ (PartF : \ 텍스트 {차 잔류} \)

시간의 이유뿐만 아니라 시험을 변경하려면 넣어 큰 형님 블로그를 처음으로 여기에, 다음에 쓰기

템플릿문제에 대한 템플릿 솔루션 :

#include<bits/stdc++.h>
using namespace std;
#define in read()
#define re register
#define fur(i,a,b) for(re int i=a;i<=b;++i)
#define fdr(i,a,b) for(re int i=a;i>=b;--i)
#define cl(a,b) memset(a,b,sizeof(a))
#define jinitaimei signed
#define int long long
inline int read()
{
    int x=0;
    char ch=getchar();
    for(;!isalnum(ch);ch=getchar());
    for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
struct num
{
    int x,y;
};
int w,q;
inline num times(num a,num b,int p)
{
    num ans;
    ans.x=(a.x*b.x%p+a.y*b.y%p*w%p+p)%p;
    ans.y=(a.y*b.x%p+a.x*b.y%p+p)%p;
    return ans;
}
inline int pow1(num a,int b,int p)
{
    num ans={1,0};
    for(;b;b>>=1,a=times(a,a,p)) if(b&1) ans=times(ans,a,p);
    return ans.x%p;
}
inline int pow2(int a,int b,int p)
{
    int ans=1;
    for(;b;b>>=1,a=a*a%p) if(b&1) ans=ans*a%p;
    return ans%p;
}
inline int sol(int n,int p)
{
    n%=p;
    if(pow2(n,(p-1)/2,p)==p-1) return -1;
    while(true)
    {
        q=rand()%p;
        w=(q*q%p-n%p+p)%p;
        if(pow2(w,(p-1)/2,p)==p-1) break;
    }
    return pow1((num){q,1},(p+1)/2,p);
}
jinitaimei main()
{
    int T=in;
    while(T--)
    {
        int n=in,p=in;
        if(!n)
        {
            puts("0");
            continue;
        }
        int ans1=sol(n,p),ans2=p-ans1;
        if(ans1==-1) puts("Hola!");
        else
        {
            if(ans1==ans2) printf("%lld\n",ans1);
            else if(ans1<ans2) printf("%lld %lld\n",ans1,ans2);
            else printf("%lld %lld\n",ans2,ans1);
        }
    }
    return 0;
}

추천

출처www.cnblogs.com/ALANALLEN21LOVE28/p/11564866.html