QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#799946 | #9619. 乘积,欧拉函数,求和 | langx_zym | WA | 699ms | 5388kb | C++20 | 3.4kb | 2024-12-05 19:42:47 | 2024-12-05 19:42:48 |
Judging History
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;
}
}
}
}
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;
}
}
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,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>(1 << 16);
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);
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;
}
詳細信息
Test #1:
score: 100
Accepted
time: 7ms
memory: 5212kb
input:
5 1 6 8 6 2
output:
892
result:
ok single line: '892'
Test #2:
score: 0
Accepted
time: 3ms
memory: 5388kb
input:
5 3 8 3 7 8
output:
3157
result:
ok single line: '3157'
Test #3:
score: -100
Wrong Answer
time: 699ms
memory: 5192kb
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'