QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#455070 | #3140. DivModulo | timics | AC ✓ | 1468ms | 134036kb | C++20 | 4.3kb | 2024-06-25 19:24:03 | 2024-06-25 19:24:03 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<double, double> pdd;
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define rep(i, from, to) for (int i = from; i < (to); ++i)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define FOR(i, to) for (int i = 0; i < (to); ++i)
typedef vector<vector<int> > vvi;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<pair<int, int> > vpi;
typedef pair<ll,ll> pll;
typedef vector<string> vs;
#define Nmax 200200
#define MOD 1000000007
ll M,N,D;
vll a, m;
class Sieve {
public:
vi fp; // first prime (i == fp[i] means it's prime itself)
vi primes; // all primes <= N
vi nump; // num unique primes
Sieve(int N) {
fp.resize(N+10);
nump.resize(N+10);
for(int i=2;i<=N;++i) {
if(!fp[i]) {
primes.pb(i);
for(int j=i;1LL*i*j<=N;++j) {
if(!fp[i*j]) fp[i*j] = i;
++nump[i*j];
}
fp[i] = i;
}
}
}
bool isPrime(int x) {
return fp[x] == x;
}
vpi getPrimes(int x) { // prime decomp of x
vpi ret;
while(x > 1) {
int p = fp[x], cnt = 0;
while(x % p == 0) {
x /= p; ++cnt;
}
ret.pb(mp(p, cnt));
}
return ret;
}
};
ll fexp(ll N, ll p) {
ll cur = 1;
ll ret = 0;
while(cur <= N/p) {
cur *= p;
ret += N/cur;
}
return ret;
}
ll pw(ll x, ll y, ll mod) {
if(!y) return 1;
if(y%2) return (x * pw(x, y-1, mod)) % mod;
ll z = pw(x, y/2, mod);
return (z*z) % mod;
}
ll divy(ll N, ll p, ll pe) {
ll per = 1; // period
for(ll i=1;i<pe;++i) {
if(i%p) per = (per * i) % pe;
}
ll ret = pw(per, N/pe, pe);
//cout<<N<<" "<<per<<" "<<N/pe<<" "<<N%pe<<endl;
for(ll i=1;i<=N%pe;++i) { // last section
if(i%p) ret = (ret * i) % pe;
}
if(N >= p) ret = (ret * divy(N/p, p, pe)) % pe;
return ret;
}
// Euclid extins
ll gcd(ll a, ll b, ll &x, ll &y) {
if(!b) { x=1; y=0; return a; }
else {
ll x0, y0, d = gcd(b,a%b,x0,y0);
x = y0; y = x0 - a/b *y0; return d;
}
}
pll euclid(ll a, ll b, ll c) { //ax - by = c;
ll x, y, sol1, sol2; ll d = gcd(a,b,x,y);
if(c%d) return mp(0,0); //no sol
else { sol1 = (c/d)*x; sol2 = -(c/d)*y; }
//only if want minimal
while(sol1 < 0 || sol2 < 0) { sol1 += b/d; sol2 += a/d;}
while(sol1 >= b/d || sol2 >= a/d) { sol1 -= b/d; sol2 -= a/d;}
return mp(sol1,sol2);
}
// Chinese remainder theorem x = a1 mod m1, x = a2 mod m2
pll crt(ll a1, ll m1, ll a2, ll m2) {
ll d = gcd(m1,m2);
pll p = euclid(m1,m2,d);
ll s = p.fs, t = -p.sc;
if (a1 % d != a2 % d) return make_pair(0, -1);
ll x = (s * a2 * m1 + t * a1 * m2) % (m1*m2);
x = (x + m1*m2) % (m1*m2);
return mp(x/d, m1*m2/d);
}
// x = a[i] (mod m[i]) also returns period (lcm)
pll chinese(vll &a, vll &m) {
pll ret = mp(a[0], m[0]);
for (int i = 1; i < a.size(); ++i) {
ret = crt(ret.fs, ret.sc, a[i], m[i]); if (ret.sc == -1) break;
}
return ret;
}
ll inv(ll N, ll mod) { // gcd(N, mod) = 1
// want a so that a * N - mod * b = 1
pii e = euclid(N, mod, 1);
if((e.fs * N) % mod != 1) cout<<"CALL THE POLICE "<<endl;
return e.fs;
}
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
cin>>M>>N>>D;
Sieve sv(D);
vpi v = sv.getPrimes(D);
vll w;
ll fit = 1000000000000000000LL;
for(auto x: v) {
ll p = x.fs, e = x.sc;
ll k = fexp(M, p) - fexp(N, p) - fexp(M-N, p);
w.pb(k);
fit = min(fit, k/e);
}
for(int i=0;i<sz(v);++i) {
ll p = v[i].fs, e = v[i].sc;
ll tot = 1; FOR(i, e) tot *= p;
ll k = w[i] - fit*e;
if(k >= e) {
a.pb(0);
m.pb(tot);
continue;
}
ll mdp = 1; // how much it is mod p^e = p^k * divy(comb, p^(e-k))
FOR(i, k) mdp *= p;
ll md = 1;
FOR(i, e-k) md *= p;
mdp = (mdp * divy(M, p, md)) % tot;
mdp = mdp * inv(divy(N, p, md), md) % tot;
mdp = mdp * inv(divy(M-N, p, md), md) % tot;
// x / p^e = mdp mod tot
ll fac = inv(D/tot, tot);
fac = pw(fac, fit, tot);
mdp = (mdp * fac ) % tot;
a.pb(mdp);
m.pb(tot);
//cout<<mdp<<" "<<tot<<endl;
}
pii sol = chinese(a, m);
FOR(i, sz(a)) {
if(sol.fs % m[i] != a[i]) cout<<"CALL THE PRIEST"<<endl;
}
cout<<sol.fs<<"\n";
return 0;
}
// A = 2*ab + 2*ac + TAB + TAC
// B = 2*ba +
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3524kb
input:
9 2 3
output:
1
result:
ok single line: '1'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3752kb
input:
5 2 5
output:
2
result:
ok single line: '2'
Test #3:
score: 0
Accepted
time: 0ms
memory: 3748kb
input:
6 3 6
output:
2
result:
ok single line: '2'
Test #4:
score: 0
Accepted
time: 0ms
memory: 3776kb
input:
7654321 1234567 1050
output:
210
result:
ok single line: '210'
Test #5:
score: 0
Accepted
time: 1468ms
memory: 132980kb
input:
5435127462024668 1811709154008222 15999989
output:
3929247
result:
ok single line: '3929247'
Test #6:
score: 0
Accepted
time: 1353ms
memory: 134036kb
input:
535133767398117960 178377922466039320 15997109
output:
8591092
result:
ok single line: '8591092'
Test #7:
score: 0
Accepted
time: 1338ms
memory: 133512kb
input:
19001660319932250 4750415079983062 15997307
output:
11654270
result:
ok single line: '11654270'
Test #8:
score: 0
Accepted
time: 18ms
memory: 21736kb
input:
97009388487133931 24252347121783482 2244216
output:
1119456
result:
ok single line: '1119456'
Test #9:
score: 0
Accepted
time: 116ms
memory: 83320kb
input:
77414571706643886 19353642926660971 9636911
output:
7878729
result:
ok single line: '7878729'
Test #10:
score: 0
Accepted
time: 0ms
memory: 3492kb
input:
79972350283733926 19993087570933481 8
output:
3
result:
ok single line: '3'
Test #11:
score: 0
Accepted
time: 116ms
memory: 75012kb
input:
4000000000000000000 120381496211536644 8483874
output:
2762130
result:
ok single line: '2762130'
Test #12:
score: 0
Accepted
time: 4ms
memory: 8868kb
input:
23404559176443690 5851139794110922 673232
output:
483392
result:
ok single line: '483392'
Test #13:
score: 0
Accepted
time: 23ms
memory: 32300kb
input:
458805763450927392 229402881725463696 3605270
output:
1084730
result:
ok single line: '1084730'
Test #14:
score: 0
Accepted
time: 0ms
memory: 4680kb
input:
17811914547110328 5937304849036776 180646
output:
63386
result:
ok single line: '63386'