QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#180454 | #7087. Counting Polygons | brz# | WA | 233ms | 173952kb | C++20 | 3.3kb | 2023-09-15 20:58:22 | 2023-09-15 20:58:22 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define maxn 10000010
#define mod 1000000007
int prime[maxn],pt=0;
bool vp[maxn];
int phi[maxn];
void SieveInit(const int N){
phi[1]=1;
for(int i=2;i<=N;i++){
if(!vp[i])prime[++pt] = i, phi[i] = i-1;
for(int j=1;j<=pt&&i*prime[j]<=N;j++){
vp[i*prime[j]] = true;
if(i%prime[j]==0){
phi[i*prime[j]] = phi[i] * prime[j];
break;
}
phi[i*prime[j]] = phi[i] * (prime[j]-1);
}
}
}
int fac[maxn],inv[maxn],inv_fac[maxn];
void FacInit(int N){
fac[0]=inv_fac[0]=inv[1]=1;
for(int i=1;i<=N;i++)fac[i]=1ll*fac[i-1]*i%mod;
for(int i=2;i<=N;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=1;i<=N;i++)inv_fac[i]=1ll*inv_fac[i-1]*inv[i]%mod;
}
int Binom(int x,int y){
if(y<0||x<y)return 0;
return 1ll*fac[x]*inv_fac[y]%mod*inv_fac[x-y]%mod;
}
void add(int &x,int y){x=(x+y>=mod?x+y-mod:x+y);}
void dec(int &x,int y){x=(x-y<0?x-y+mod:x-y);}
int add(int x){return x>=mod?x-mod:x;}
int dec(int x){return x<0?x+mod:x;}
int ksm(int x,int y){
int re=1;
for(;y;y>>=1){
if(y&1)re=1ll*re*x%mod;
x=1ll*x*x%mod;
}
return re;
}
int main()
{
SieveInit(maxn-10);
FacInit(maxn-10);
int Te;cin>>Te;while(Te--){
int n,m;
cin>>n>>m;
int ans=0;
auto calc=[&](int x,int y){
return Binom(x-1,y-1);
};
auto solve=[&](int d){
if(n%(m/d))return;
int N = n / (m/d);
// printf("solve : %d %d %d %d\n", d, N, calc(N,d), phi[m/d]);
add(ans, 1ll*calc(N, d) * phi[m/d]%mod);
return;
};
for(int i=1;i*i<=m;i++)
if(m%i==0){
solve(i);
if(i*i != n)solve(m/i);
}
int p = (n-1)/2;
dec(ans, 1ll*m * calc(n-p, m) %mod);
if(m%2==1){
if(n&1){
// printf("ans : %d -> ",ans);
add(ans, 1ll*calc(n/2, m/2) * m%mod);
// printf("%d -> ",ans);
add(ans, 1ll*calc(n/2, m/2+1) * m%mod);
// printf("%d -> ",ans);
dec(ans, 1ll*calc(n/2/2, m/2) * m%mod);
// printf("%d -> ",ans);
dec(ans, 1ll*calc(n/2/2, m/2+1) * m%mod);
// printf("%d\n",ans);
}
else{
add(ans, 1ll*calc(n/2, m/2+1) * m%mod);
dec(ans, 1ll*calc(n/2/2, m/2+1) * m%mod);
dec(ans, 1ll*calc(n/2/2, m/2) * m%mod);
}
}else{
if(n%2==0)add(ans, 1ll*calc(n/2, m/2) * (m/2)%mod);
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
if((n-i-j)%2==0){
add(ans, 1ll*calc((n-i-j)/2,m/2+1) * (m/2)%mod);
if(i)add(ans, 1ll*calc((n-i-j)/2,m/2) * (m/2)%mod);
if(j)add(ans, 1ll*calc((n-i-j)/2,m/2) * (m/2)%mod);
if(i&&j)add(ans, 1ll*calc((n-i-j)/2,m/2-1) * (m/2)%mod);
if(!i && !j){
dec(ans, 2ll*calc((n-i-j)/2/2,m/2+1) * (m/2)%mod);
dec(ans, 4ll*calc((n-i-j)/2/2,m/2) * (m/2)%mod);
}else if(i && j){
dec(ans, 2ll*calc((n-i-j)/2/2,m/2+1) * (m/2)%mod);
dec(ans, 4ll*calc((n-i-j)/2/2,m/2) * (m/2)%mod);
dec(ans, 2ll*calc((n-i-j)/2/2,m/2-1) * (m/2)%mod);
}else{
dec(ans, 1ll*calc((n-i-j)/2/2,m/2+1) * (m/2)%mod); // 1 + n/2 , 0
dec(ans, 1ll*calc((n-i-j)/2/2,m/2) * (m/2)%mod);
dec(ans, 1ll*calc((n-i-j)/2/2,m/2+1) * (m/2)%mod);// 0 + n/2 , 1
dec(ans, 1ll*calc((n-i-j)/2/2,m/2) * (m/2)%mod);
dec(ans, 1ll*calc((n-i-j)/2/2,m/2-1) * (m/2)%mod);
}
}
}
ans=1ll*ans*ksm(2*m,mod-2)%mod;
cout<<ans<<'\n';
}
}
/*
1
7 4
*/
详细
Test #1:
score: 100
Accepted
time: 179ms
memory: 173900kb
input:
4 3 3 4 3 5 3 7 4
output:
1 0 1 3
result:
ok 4 tokens
Test #2:
score: -100
Wrong Answer
time: 233ms
memory: 173952kb
input:
10000 8708700 6531525 8062080 4031040 7068600 2356200 3659040 332640 7309575 2088450 5503680 1572480 7162848 3581424 9831360 7724640 6306300 5045040 5783400 2891700 4677120 2338560 5110560 786240 9525600 2381400 6955200 4173120 8229375 3291750 7068600 5405400 9639000 3213000 5969040 2984520 5274360 ...
output:
70575804 411063145 825888409 442348736 757290919 973711772 657961379 482306068 808445792 611975449 89376781 382525873 820983297 356837429 8399710 201203710 29208731 199547321 595050658 982243306 632144614 975420242 618401084 494630952 190742484 539447570 777843241 239132520 402932842 865811879 67886...
result:
wrong answer 2nd words differ - expected: '911063149', found: '411063145'