QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#737821 | #9619. 乘积,欧拉函数,求和 | pmt2018 | WA | 390ms | 16576kb | C++17 | 5.8kb | 2024-11-12 16:55:52 | 2024-11-12 16:55:53 |
Judging History
answer
/*
Problem : A. 乘积,欧拉函数,求和
Url : https://qoj.ac/contest/1840/problem/9619
Date : 2024/11/12 16:19:40
Solver : pmt2018
*/
#include<bits/stdc++.h>
#define y0 pmtx
#define y1 pmtxx
#define x0 pmtxxx
#define x1 pmtxxxx
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define DEBUG printf("Passing Line %d in function [%s].\n",__LINE__,__FUNCTION__)
using namespace std;
typedef pair<int ,int > pii;
typedef vector<int > vi;
typedef long long ll;
typedef unsigned long long ull;
namespace FastIO{
const int SIZE=(1<<20);
char in[SIZE],*inS=in,*inT=in+SIZE;
inline char Getchar(){
if(inS==inT){inT=(inS=in)+fread(in,1,SIZE,stdin);if(inS==inT)return EOF;}
return *inS++;
}
char out[SIZE],*outS=out,*outT=out+SIZE;
inline void Flush(){fwrite(out,1,outS-out,stdout);outS=out;}
inline void Putchar(char c){*outS++=c;if(outS==outT)Flush();}
struct NTR{~NTR(){Flush();}}ZTR;
}
#ifndef LOCAL
#define getchar FastIO::Getchar
#define putchar FastIO::Putchar
#endif
template<typename T> inline void read(T &x){
x=0;int f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
x*=f;
}
inline void readstr(char* str){
int len=0;char c=getchar();
while(c==' '||c=='\n')c=getchar();
while(c!=' '&&c!='\n'&&c!='\r')str[len++]=c,c=getchar();
str[len] = '\0';
}
template<typename T>inline void write(T x){
if(!x)putchar('0');
if(x<0)x=-x,putchar('-');
static int sta[20];int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline void writestr(char* str){int cur=0;while(str[cur])putchar(str[cur++]);}
const int maxn=200007,INF=0x3f3f3f3f;
const ll MOD=998244353;
const ll LINF=0x3f3f3f3f3f3f3f3fll;
const ll P=19260817;
template<typename T>inline void ckmax(T &x,T y){x=(y>x?y:x);}
template<typename T>inline void ckmin(T &x,T y){x=(y<x?y:x);}
template<typename T>inline T my_abs(T x){if(x<0)x=-x;return x;}
inline int mod1(int x){return x<MOD?x:x-MOD;}
inline int mod2(int x){return x<0?x+MOD:x;}
inline void add(int &x,int y){x=mod1(x+y);}
inline void sub(int &x,int y){x=mod2(x-y);}
int n, a[maxn];
int N=3000;
bool vis[maxn];
int num[maxn],tot;
int big[maxn],pr[maxn];
// vector<int > pr;
vector<int > fr[maxn];
int to[57];
int mask[maxn];
int cnt[maxn][20];
void init_prime(){
to[2]=0,to[3]=1,to[5]=2,to[7]=3,to[11]=4;
to[13]=5,to[17]=6,to[19]=7,to[23]=8,to[29]=9;
to[31]=10,to[37]=11,to[41]=12,to[43]=13,to[47]=14;
for(int i=2;i<=N;i++){
if(!vis[i]){
pr[tot]=i,num[i]=tot++;
for(int j=i;j<=N;j+=i){
if(j!=i)vis[j]=true;
fr[j].pb(i);
}
}
}
for(int i=2;i<=N;i++){
for(int x:fr[i]){
if(x<=47){
int cur=i;
while(cur%x==0){
cnt[i][to[x]]++;
cur/=x;
}
if(cnt[i][to[x]]&1)mask[i]|=(1<<to[x]);
}
else big[i]=x;
}
}
}
int pre[1<<15];
int frac[maxn], ifrac[maxn], inv[maxn];
int qpow(int a, int b) {
int ret = 1;
while(b) {
if(b&1)ret=1ll*ret*a%MOD;
b>>=1;
a=1ll*a*a%MOD;
}
return ret;
}
void init_pre(){
frac[0] = 1;
for (int i = 1; i <= N; i++) frac[i] = 1ll * frac[i-1] * i % MOD;
ifrac[N] = qpow(frac[N], MOD - 2);
for (int i = N; i >= 1; i--) {
ifrac[i - 1] = 1ll * i * ifrac[i] % MOD;
inv[i] = 1ll * ifrac[i] * frac[i - 1] % MOD;
}
pre[0] = 1;
for(int s = 1; s < (1 << 15); s++) {
pre[s] = 1;
for(int i = 0; i < 15; i ++) {
if(s & (1<<i))
pre[s] = 1ll * pre[s] * (pr[i] - 1) % MOD * inv[pr[i]] % MOD;
}
}
}
int dp[1<<15];
int tmp[1<<15];
int ndp[2][1<<15], ntmp[2][1<<15];
void solve(int bigp) {
for(int s = 0; s < (1 << n); s++) ndp[0][s] = dp[s];
for(int i = 1; i <= n; i++) {
// cout<<big[i]<<endl;
if(big[a[i]] != bigp) continue;
for(int s = 0; s < (1 << 15); s ++)
ntmp[0][s] = ndp[0][s], ntmp[1][s] = ndp[1][s];
for(int s = 0; s < (1 << n); s++){
int ns = s | mask[a[i]];
int nw = ns ^ s;
add(ntmp[1][ns], 1ll * ndp[1][s] * a[i] % MOD * pre[nw] % MOD);
add(ntmp[1][ns], 1ll * ndp[0][s] * a[i] % MOD * pre[nw] % MOD
* (bigp - 1) % MOD * inv[bigp] % MOD);
}
for(int s = 0; s < (1 << 15); s ++)
ndp[0][s] = ntmp[0][s], ndp[1][s] = ntmp[1][s];
}
for(int s = 0; s < (1 << n); s++) dp[s] = mod1(ndp[0][s] + ndp[1][s]);
}
int main(){
init_prime();
init_pre();
read(n);
for(int i = 1; i <= n; i++) {
read(a[i]);
}
dp[0] = 1;
for(int i = 1; i <= n; i++) {
if(!big[a[i]]) {
// cout<<a[i]<<' ' << bitset<5>(mask[a[i]])<<endl;
for(int s = 0; s < (1 << 15); s ++) tmp[s] = dp[s];
for(int s = 0; s < (1 << 15); s ++) {
int ns = s | mask[a[i]];
int nw = ns ^ s;
add(tmp[ns], 1ll * dp[s] * a[i] % MOD * pre[nw] % MOD);
}
for(int s = 0; s < (1 << 15); s ++) dp[s] = tmp[s];
}
}
for(int b = 15; b < tot; b ++) {
solve(pr[b]);
}
int ans = 0;
for(int s = 0; s < (1 << 15); s ++) {
add(ans, dp[s]);
}
printf("%d", ans);
return 0;
}
//things to remember
//1.long long
//2.array length
//3.freopen
//4 boarder case
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 12804kb
input:
5 1 6 8 6 2
output:
892
result:
ok single line: '892'
Test #2:
score: 0
Accepted
time: 7ms
memory: 16576kb
input:
5 3 8 3 7 8
output:
3157
result:
ok single line: '3157'
Test #3:
score: -100
Wrong Answer
time: 390ms
memory: 13464kb
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:
163575413
result:
wrong answer 1st lines differ - expected: '50965652', found: '163575413'