암 \ (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;
}
아이디어 매우 흥미로운, 당신은 질문에 이가지 경우 볼 필요 (사용 가능한 \ (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;
}