完全不懂。十年前的 Linux 机子上跑洛谷上超时的 #18 号点只需要 0.8s。但是开 ASan 之后显示挂了,开 gdb 又没爆哪里挂了。
后三个点都 T 了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
#define fi first
#define se second
#define endl '\n'
#define mkp make_pair
#define pb push_back
#define all(x) x.begin(),x.end()
#define Cl(x) memset(x,0,sizeof(x))
const bool DC=0;
const ll mod=998244353;
const int N=100005;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll qpow(ll a,ll b,ll p=mod){ll ans=1;for(a%=p,b%=p-1;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p;return ans;}
void NO(){cout<<"NO\n";}
void YES(){cout<<"YES\n";}
mt19937 rnd((unsigned long long)new char);
int rnad(){return abs((int)rnd());}
int rd(int l,int r){return rnad()%(r-l+1)+l;}
const ll INF=0x3f3f3f3f3f3f3f3fll,inf=0x3f3f3f3f;
bool isnp[1<<14];vector<int>pr;
int pid[1<<14],q[1<<14],a[1<<14],sum[1<<14];
int ps[1<<14];
ll f[1<<13][1<<13];
void init(){
isnp[1]=1;
for(int i=2;i<=2000;i++){
if(!isnp[i])pr.push_back(i),pid[i]=pr.size()-1;
for(auto j:pr)if(j){
if(i*j>2000)break;
isnp[i*j]=1;
if(i%j==0)break;
}
}
for(auto i:pr){
for(int j=i;j<=2000;j+=i){
ps[j]=i;
if(i<=41)q[j]|=1<<pid[i];
}
}
}
void __INIT__(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
void __SOLVE__(int _case){
init();
int n,x;
cin>>n;
while(n--)cin>>x,a[x]++;
for(int i=0;i<(1<<13);i++){
for(int j=2;j<=2000;j++)if(!(q[j]&i))(f[i][ps[j]]+=a[j])%=mod,sum[i]+=a[j];
sum[i]+=a[1];
}
int m;
cin>>m;
while(m--){
ll Sum=0;
vector<int>v;
int c;cin>>c;
int ls=0;
while(c--){
ll x;cin>>x;
v.push_back(x);
if(pid[x]<13)ls|=1<<pid[x];
}
sort(all(v));
for(int s=0;s<(1<<13);s++)if((s|ls)==ls){
ll ans=1;int S=sum[s];
for(auto i:v)if(i>=43){
(ans*=qpow(2,f[s][i])-1)%=mod;
S-=f[s][i];
}
(ans*=qpow(2,S))%=mod;
(Sum+=(__builtin_popcount(s)&1)?mod-ans:ans)%=mod;
}
cout<<Sum<<"\n";
}
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
__INIT__();int T;DC?cin>>T,1:T=1;
for(int _CASE=1;_CASE<=T;_CASE++)__SOLVE__(_CASE);
return 0;}