?
# | Author | Problem | Lang | Verdict | Time | Memory | Sent | Judged | |
---|---|---|---|---|---|---|---|---|---|
196227451 |
Practice: jackylova_fan_fan_fan |
1794D - 29 | C++17 (GCC 9-64) | Wrong answer on test 9 | 109 ms | 200924 KB | 2023-03-06 11:35:51 | 2023-03-06 11:35:51 |
// Author:dd //(double)clock() / CLOCKS_PER_SEC <= 0.95 #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; #define _CRT_SECURE_NO_WARNINGS #define pb push_back #define pii pair<int,int> #define pll pair<long long,long long> #define pil pair<int,long long> #define fer(i,a,n) for(int i=(a);i<=(n);++i) #define rep(i,n,a) for(int i=(n);i>=(a);--i) #define ferl(i,a,n) for(long long i=(a);i<=(n);++i) #define repl(i,n,a) for(long long i=(n);i>=(a);--i) #define fi first #define se second #define elif else if #define no cout<<"NO\n"; #define yes cout<<"YES\n"; #define none cout<<"-1\n"; #define mul_t int _t;cin>>_t;while(_t--) #define FASTIO ios::sync_with_stdio(false);cin.tie(0); #define Hash gp_hash_table #define all(x) x.begin()+1,x.end() template<class T> void print(const T& t) { cout << t; } template<class T, class...args> void print(const T& t, const args&...rest) { cout << t << ' '; print(rest...); } typedef long long ll; typedef tree<int,null_type,less_equal<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_int_set; typedef tree<long long,null_type,less_equal<long long>,rb_tree_tag,tree_order_statistics_node_update> ordered_ll_set; const int int_inf= 0x3f3f3f3f; const ll ll_inf=1e16; ll qpow(ll a,ll k,ll mod){ll res=1;a%=mod;while(k){if(k&1)res=res*a%mod;a=a*a%mod;k>>=1;}return res;} template<class T1,class T2> void mul(T1&x,T2 y,ll mod){x=(x+mod)%mod,y=(y+mod)%mod,x=(x*y)%mod;} template<class T1,class T2> void dif(T1&x,T2 y,ll mod){x=(x+mod)%mod,y=qpow(y,mod-2,mod),x=(x*y)%mod;} template<class T1,class T2> void add(T1&x,T2 y,ll mod){x=(x+mod)%mod,y=(y+mod)%mod,x=(x+y)%mod;} template<class T1,class T2> void dec(T1&x,T2 y,ll mod){x=(x+mod)%mod,y=(y+mod)%mod,x=(x-y+mod)%mod;} template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} //exgcd ax+by=gcd(a,b) ax+by=z (z > a*b-a-b) template<class T> T exgcd(T a,T b,T &x,T &y){T d=a;if(b==0)x=1,y=0;else{d=exgcd(b,a%b,y,x),y-=a/b*x;}return d;} vector<bool>isnotprime; vector<int>primes; void getprime(int n){isnotprime.resize(n+1,0);isnotprime[1]=1;for(int i=2;i<=n;i++){if(isnotprime[i]==0)primes.push_back(i);for(size_t j=0;j<primes.size()&&i*primes[j]<=n;j++){isnotprime[i*primes[j]]=1;if(i%primes[j]==0)break;}}} //求欧拉函数 ∑(d|n)φ(d)=n vector<ll>phi; void getphi(int n){isnotprime.resize(n+1,0);phi.resize(n+1,0);phi[1]=1,isnotprime[1]=1;for(int i=2;i<=n;i++){if(isnotprime[i]==0){primes.push_back(i);phi[i]=i-1;}for(size_t j=0;j<primes.size()&&i*primes[j]<=n;j++){isnotprime[i*primes[j]]=1;if(i%primes[j]==0){phi[i*primes[j]]=phi[i]*primes[j];break;}phi[i*primes[j]]=phi[i]*(primes[j]-1);}}} struct combination{combination(int n,ll mo){siz=n,mod=mo;inv.resize(n+1,1),preinv.resize(n+1,1),fac.resize(n+1,1);for(int i=2;i<=n;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod,preinv[i]=preinv[i-1]*inv[i]%mod;for(long long i=2;i<=n;i++)fac[i]=fac[i-1]*i%mod;}ll C(int n,int m){if(n==0&&m==0)return 1;if(n<m||m<0||n<0)return 0;return fac[n]*preinv[m]%mod*preinv[n-m]%mod;}ll A(int n,int m){if(n==0&&m==0)return 1;if(n<m||m<0||n<0)return 0;return fac[n]*preinv[n-m]%mod;}vector<ll>inv;vector<ll>preinv;vector<ll>fac;private:int siz;ll mod;}; struct dsu{vector<int>fa,siz;dsu(int n){fa.resize(n+1),siz.resize(n+1);for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1;}int ffind(int x){return x==fa[x]?x:fa[x]=ffind(fa[x]);}bool uuion(int x,int y){x=ffind(x),y=ffind(y);if(x==y)return false;if(siz[x]<siz[y])swap(x,y);fa[y]=x,siz[x]+=siz[y],siz[y]=0;return true;}bool check(int x,int y){return ffind(x)==ffind(y);}void init(){for(size_t i=1;i<=fa.size()-1;i++)fa[i]=i,siz[i]=1;}int getsize(int x){return siz[x];}}; template<class T> struct segtree{int siz;vector<T>sum,minn,maxx,a;segtree(vector<T>&v){a=v;siz=a.size()-1;sum.resize(siz*4+1),minn.resize(siz*4+1),maxx.resize(siz*4+1);build(1,1,siz);}void upchange(int k,int l,int r,int x,T y){if(l==r){sum[k]=minn[k]=maxx[k]=y;return;}int mid=(l+r)>>1;if(x<=mid)upchange(k<<1,l,mid,x,y);else upchange(k<<1|1,mid+1,r,x,y);up(k);}void upadd(int k,int l,int r,int x,T y){if(l==r){sum[k]+=y,minn[k]+=y,maxx[k]+=y;return;}int mid=(l+r)>>1;if(x<=mid)upadd(k<<1,l,mid,x,y);else upadd(k<<1|1,mid+1,r,x,y);up(k);}T qsum(int k,int l,int r,int x,int y){if(l==x&&r==y)return sum[k];int mid=(l+r)>>1;if(y<=mid)return qsum(k<<1,l,mid,x,y);else if(x>mid)return qsum(k<<1|1,mid+1,r,x,y);else return qsum(k<<1,l,mid,x,mid)+qsum(k<<1|1,mid+1,r,mid+1,y);}T qmin(int k,int l,int r,int x,int y){if(l==x&&r==y)return minn[k];int mid=(l+r)>>1;if(y<=mid)return qmin(k<<1,l,mid,x,y);else if(x>mid)return qmin(k<<1|1,mid+1,r,x,y);else return min(qmin(k<<1,l,mid,x,mid),qmin(k<<1|1,mid+1,r,mid+1,y));}T qmax(int k,int l,int r,int x,int y){if(l==x&&r==y)return maxx[k];int mid=(l+r)>>1;if(y<=mid)return qmax(k<<1,l,mid,x,y);else if(x>mid)return qmax(k<<1|1,mid+1,r,x,y);else return max(qmax(k<<1,l,mid,x,mid),qmax(k<<1|1,mid+1,r,mid+1,y));}private:void build(int k,int l,int r){if(l==r){sum[k]=minn[k]=maxx[k]=a[l];return;}int mid=(l+r)>>1;build(k<<1,l,mid),build(k<<1|1,mid+1,r);up(k);}void up(int k){sum[k]=sum[k<<1]+sum[k<<1|1],minn[k]=min(minn[k<<1],minn[k<<1|1]),maxx[k]=max(maxx[k<<1],maxx[k<<1|1]);}}; struct Bitcounter{template<class T>T reversebit(T x){int f=1;if(x<0)x=-x,f=-1;vector<int>v;while(x){v.push_back(x&1);x>>=1;}reverse(v.begin(),v.end());T now=1,ans=0;for(auto&x:v)ans+=x*now,now<<=1;return ans*f;}template<class T>T lowbit(T x){return x&-x;}template<class T>int countbit(T x){int sum=0;while(x)sum+=x&1,x>>=1;return sum;}template<class T>void setbit(int*arr,T x){int cnt=0;while(x)arr[cnt]=x&1,x>>=1,++cnt;}ll getbit(int*arr,int n=61){ll sum=0;for(int i=0;i<n;i++)sum+=arr[i],sum<<=1;sum+=arr[n];return sum;}}; template<class T> T reverseD(T x){int f=1;if(x<0)x=-x,f=-1;vector<int>v;while(x){v.push_back(x%10);x/=10;}reverse(v.begin(),v.end());T now=1,ans=0;for(auto&x:v)ans+=x*now,now*=10;return ans*f;} template<class T1,class T2> ll updiv(T1 a,T2 b){if(a<0)return a/b;return a/b+(a%b!=0);} template<class T1,class T2> ll downdiv(T1 a,T2 b){if(a>0)return a/b;return a/b-(a%b!=0);} void strerase(string&s,char c){string t;for(auto&ch:s){if(ch==c)continue;t+=ch;}s=t;} template<class T1,class T2> void cmin(T1&a,T2 b){a=min<T1>(a,b);} template<class T1,class T2> void cmax(T1&a,T2 b){a=max<T1>(a,b);} //------------------------------------------- const ll mod=998244353; combination cb(5050,mod); ll dp[5050][5050]; void solve() { int n; cin>>n; vector<int>v(n*2+1); fer(i,1,n*2)cin>>v[i]; map<int,ll>p,np; fer(i,1,n*2)isnotprime[v[i]]?np[v[i]]++:p[v[i]]++; if(p.size()<n){cout<<0;return;} ll k=cb.fac[n]; for(auto [a,b]:np) { if(b==0)continue; mul(k,cb.inv[b],mod); } dp[0][0]=1; int cnt=0; for(auto [a,b]:p) { if(b==0)continue; ++cnt; fer(i,0,cnt) { if(i)add(dp[cnt][i],dp[cnt-1][i-1]*cb.inv[b-1]%mod,mod); add(dp[cnt][i],dp[cnt-1][i]*cb.inv[b]%mod,mod); } } cout<<dp[p.size()][n]*k%mod; } signed main() { FASTIO #define OJ #ifndef OJ freopen(".in", "r", stdin); freopen(".out", "w", stdout); #endif getprime(1000001); solve(); } /* 1.深呼吸,不要紧张,慢慢读题,读明白题,题目往往比你想的简单。 2.暴力枚举:枚举什么,是否可以使用一些技巧加快枚举速度(预处理、前缀和、数据结构、数论分块)。 3.贪心:需要排序或使用数据结构(pq)吗,这么贪心一定最优吗。 4.二分:满足单调性吗,怎么二分,如何确定二分函数返回值是什么。 5.位运算:按位贪心,还是与位运算本身的性质有关。 6.数学题:和最大公因数、质因子、取模是否有关。 7.dp:怎么设计状态,状态转移方程是什么,初态是什么,使用循环还是记搜转移。 8.搜索:dfs 还是 bfs ,搜索的时候状态是什么,需要记忆化吗。 9.树上问题:是树形dp、树上贪心、或者是在树上搜索。 10.图论:依靠什么样的关系建图,是求环统计结果还是最短路。 11.组合数学:有几种值,每种值如何被组成,容斥关系是什么。 12.交互题:log(n)次如何二分,2*n 次如何通过 n 次求出一些值,再根据剩余次数求答案。 13.如果以上几种都不是,多半是有一个 point 你没有注意到。 */
?
?
?
?