[Sdoi2017]数字表格
错误的数字表格([Sdoi2017]数字表格 ,将求积看成求和)
#include<bits/stdc++.h>
#define int long long
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
const int N = 1e6 + 3, M = 10 * N + 7;
const int mod = 1e9 + 7;
int T;
int n;
int m;
int cnt;
int mu[N];
int fib[N];
int pri[N];
int sum[N];
bool st[N];
inline int read()
{
int x = 0;
char c = getchar_unlocked();
for(;!isdigit(c);c = getchar_unlocked());
for(;isdigit(c);x = x * 10 + c - 48,c = getchar_unlocked());
return x;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
inline void init()
{
mu[1] = 1;
fib[1] = 1;
for(int i = 2;i < N;i ++)
{
fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
if(!st[i]) pri[++ cnt] = i,mu[i] = -1;
for(int j = 1;pri[j] * i < N && j <= cnt;j ++)
{
st[i * pri[j]] = 1;
if((i % pri[j]) == 0)
{
mu[i * pri[j]] = 0;
break;
}
mu[i * pri[j]] = -mu[i];
}
}
for(int i = 1;i < N;i ++)
{
for(int j = 1;i * j < N;j ++)//T = i * j k = i T / k = j
{
// cout << sum[i * j] << ' ' << (fib[i] * mu[j] % mod) << '\n';
sum[i * j] = (sum[i * j] + ((fib[i] * mu[j]) % mod) + mod) % mod;
}
}
// for(int i = 1;i < N;i ++) write(sum[i]),ent;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
T = read();
init();
while(T --)
{
n = read();
m = read();
if(n > m) swap(n,m);
int res = 0;
for(int l = 1,r;l <= n;l = r + 1)
{
r = min(n / (n / l),m / (m / l));
cout << l << ' ' << r << '\n';
res = res + ((n / l) * (m / l)) % mod * (sum[r] - sum[l - 1]) % mod;
}
write(res);ent;
}
Blue_Archive;
}
正确的数字表格([Sdoi2017]数字表格)
#include<bits/stdc++.h>
#define int long long
#define Blue_Archive return 0
#define con putchar_unlocked(' ')
#define ent putchar_unlocked('\n')
using namespace std;
const int N = 1e6 + 1;
const int mod = 1e9 + 7;
int T;
int n;
int m;
int cnt;
int g[N];
int mu[N];
int fib[N];
int pri[N];
int sum[N];
bool st[N];
inline int read()
{
int x = 0;
char c = getchar_unlocked();
for(;!isdigit(c);c = getchar_unlocked());
for(;isdigit(c);x = x * 10 + c - 48,c = getchar_unlocked());
return x;
}
inline void write(int x)
{
if(x < 0) putchar_unlocked('-'),x = -x;
if(x > 9) write(x / 10);
putchar_unlocked(x % 10 + '0');
}
inline int qpow(int a,int b)
{
int res = 1;
while(b)
{
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
inline void init()
{
g[0] = g[1] = 1;
mu[1] = 1;
fib[1] = 1;
sum[0] = sum[1] = 1;
for(int i = 2;i < N;i ++)
{
fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
g[i] = qpow(fib[i],mod - 2);
sum[i] = 1;
if(!st[i]) pri[++ cnt] = i,mu[i] = -1;
for(int j = 1;pri[j] * i < N && j <= cnt;j ++)
{
st[i * pri[j]] = 1;
if((i % pri[j]) == 0)
{
mu[i * pri[j]] = 0;
break;
}
mu[i * pri[j]] = -mu[i];
}
}
for(int i = 1;i < N;i ++)
{
for(int j = 1;i * j < N;j ++)//T = i * j k = i T / k = j
{
if(!mu[i]) continue;
if(mu[i] == -1) sum[i * j] = (sum[i * j] * g[j] % mod) % mod;
else sum[i * j] = (sum[i * j] * fib[j] % mod) % mod;
}
}
for(int i = 1;i < N;i ++) sum[i] = sum[i] * sum[i - 1] % mod;
// for(int i = 1;i < N;i ++) write(sum[i]),ent;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
init();
T = read();
while(T --)
{
n = read();
m = read();
if(n > m) swap(n,m);
int tmp,ans = 1;
for(int l = 1,r;l <= n;l = r + 1)
{
r = min(n / (n / l),m / (m / l));
tmp = sum[r] * qpow(sum[l - 1],mod - 2) % mod;
ans = ans * qpow(tmp,(n / l) * (m / l) % (mod - 1)) % mod;
}
write(ans);ent;
}
Blue_Archive;
}
与你的日常,便是奇迹

浙公网安备 33010602011771号