A
B

[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;
}

posted @ 2025-07-31 21:44  MyShiroko  阅读(12)  评论(0)    收藏  举报