QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#799964#9619. 乘积,欧拉函数,求和langx_zymWA 872ms5188kbC++203.4kb2024-12-05 19:49:472024-12-05 19:49:52

Judging History

你现在查看的是最新测评结果

  • [2024-12-05 19:49:52]
  • 评测
  • 测评结果:WA
  • 用时:872ms
  • 内存:5188kb
  • [2024-12-05 19:49:47]
  • 提交

answer

#include<bits/stdc++.h>
#define PII pair<int,int>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x&-(x))
#define VVI vector<vector<int>>
#define int long long
using namespace std;
vector<int> p = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};//16
const int maxn = 2e3 + 9,mod = 998244353;
struct FWT {
	int P = 998244353;
	//a开两倍以上或加边界处理,正变换type = 1,逆变换type = -1。
	void Or(vector<ll> &a, ll type, int n) { // 迭代实现,常数更小
		for (ll x = 2; x <= n; x <<= 1) {//当前阶段的区间大小
			ll k = x >> 1;//区间大小的一半
			for (ll i = 0; i < n; i += x) { // 左端点
				for (ll j = 0; j < k; j++) { // 偏移量
					if(i + j + k > n) break;
					(a[i + j + k] += (a[i + j] * type + P) % P) %= P;
				}
			}
		}
	}
	void And(vector<ll> &a, ll type,int n) {
		for (ll x = 2; x <= n; x <<= 1) {
			ll k = x >> 1;
			for (ll i = 0; i < n; i += x) {
				for (ll j = 0; j < k; j++) {
					(a[i + j] += a[i + j + k] * type) %= P;
				}
			}
		}
	}
	void Xor(vector<ll> &a, ll type,int n) {//逆变换时type为1/2
		for (ll x = 2; x <= n; x <<= 1) {
			ll k = x >> 1;
			for (ll i = 0; i < n; i += x) {
				for (ll j = 0; j < k; j++) {
					(a[i + j] += a[i + j + k]) %= P;
					(a[i + j + k] = a[i + j] - a[i + j + k] * 2) %= P;
					(a[i + j] *= type) %= P;
					(a[i + j + k] *= type) %= P;
				}
			}
		}
	}
};
struct node{
	int mxp,val,s;
	bool operator<(const node &b)const{
		return mxp < b.mxp;
	}
	node(){}
	node(int x){
		this->val = x;
		this->s = 0;
		for(int i = 0;i < 16;i ++){
			int v = p[i];
			while(x % v == 0) {
				s |= (1 << i);
				x /= v;
			}
		}
		this->mxp = x;
	}
}a[maxn];
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;
}
vector<int> invp,vid;
vector<int> dp;
int lim = (1<<16);
void gdp(int l,int r,int mxp){
	dp.assign(lim+5,0);
	dp[0] = 1;
	for(int i = l;i <= r;i ++){
		auto ndp = dp;
		for(int t = 0;t < lim;t ++){
			int ns = t | a[i].s;
			ndp[ns] += dp[t] * a[i].val % mod;
			ndp[ns] %= mod;
		}
		dp = ndp;
	}
	if(mxp != 1){
		int inv = invp[lower_bound(p.begin(),p.end(),mxp) - p.begin()];
		dp[0] = (dp[0] - 1 + mod) % mod * (mxp - 1) % mod * inv % mod;
		dp[0] = (dp[0] + 1) % mod;
		for(int t = 1;t < lim;t ++){
			dp[t] = dp[t] * (mxp - 1) % mod * inv % mod;
		}
	}
}
void solve(){
	int n;
	cin >> n;
	for(int i = 1;i <= n;i ++){
		int x;
		cin >> x;
		a[i] = node(x);
	}
	sort(a + 1,a + 1 + n);
	invp = vector<int>(16);
	vid = vector<int>(lim+5);
	for(int i = 0;i < 16;i ++){
		invp[i] = qpow(p[i],mod - 2);
		vid[qpow(2,i)] = i;
	}
	FWT fwt = FWT();
	vector<int> ans(lim+5);
	ans[0] = 1;
	fwt.Or(ans,1,lim);
	for(int l = 1,r = 1;l <= n;l = r){
		while(r <= n && a[r].mxp == a[l].mxp) r ++;
		gdp(l,r - 1,a[l].mxp);
		fwt.Or(dp,1,lim);
		for(int t = 0;t < lim;t ++){
			ans[t] = ans[t] * dp[t] % mod;
		}
	}
	fwt.Or(ans,-1,lim);
	int res = 0;
	for(int t = 0;t < lim;t ++){
		int x = ans[t];
		int s = t;
		while(s){
			int i = vid[lowbit(s)];
			x = x * (p[i] - 1) % mod * invp[i] % mod; 
			s -= lowbit(s);
		}
		res += x;
		res %= mod;
	}
	cout << (res + mod) % mod << '\n';
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t = 1;
//	cin >> t;
	while(t --){
		solve();
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 8ms
memory: 5188kb

input:

5
1 6 8 6 2

output:

892

result:

ok single line: '892'

Test #2:

score: 0
Accepted
time: 8ms
memory: 5164kb

input:

5
3 8 3 7 8

output:

3157

result:

ok single line: '3157'

Test #3:

score: -100
Wrong Answer
time: 872ms
memory: 5172kb

input:

2000
79 1 1 1 1 1 1 2803 1 1 1 1 1 1 1609 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2137 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 613 1 499 1 211 1 2927 1 1 1327 1 1 1123 1 907 1 2543 1 1 1 311 2683 1 1 1 1 2963 1 1 1 641 761 1 1 1 1 1 1 1 1 1 1 1 1489 2857 1 1 1 1 1 1 1 1 1 1 1 1 1 967 1 821 1 1 1 1 2143 1861...

output:

318794818

result:

wrong answer 1st lines differ - expected: '50965652', found: '318794818'