• 【NOIp2019模拟】—题解


    T1

    很显然就是钦定一些质数的出现次数在一个范围之间的所有情况
    就是枚举几个不满足上下界的条件

    就得到每个质因子可以选择的范围
    就可以随便算方案数了

    实际上上下界不满足都只会让系数1-1
    把上下界一个不满足的情况分开讨论就可以做到O(3pnum)O(3^{p_{num}})次方了

    #include<bits/stdc++.h>
    using namespace std;
    #define gc getchar
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    #define re register
    #define pb push_back
    #define cs const
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define ll long long
    #define poly vector<int>
    #define bg begin
    cs int mod=998244353;
    inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
    inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
    inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
    inline void Dec(int &a,int b){(a-=b)<0?(a+=mod):0;}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline int mul(int a,int b,int Mod){return 1ll*a*b>=Mod?1ll*a*b%Mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b){
    	int res=1;
    	for(;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));return res;
    }
    inline void chemx(ll &a,ll b){a<b?a=b:0;}
    inline void chemn(ll &a,ll b){a>b?a=b:0;}
    inline ll ksm(ll a,ll b,cs ll &mod){
    	ll res=1;
    	for(;b;b>>=1,a=mul(a,a,mod))if(b&1)res=mul(res,a,mod);
    	return res;
    }
    cs int N=1000005,M=N-5;
    bool isp[N];
    int pr[N],tot;
    inline void init(){
    	for(int i=2;i<=M;i++){
    		if(!isp[i])pr[++tot]=i;
    		for(int j=1;j<=tot&&i*pr[j]<=M;j++){
    			isp[i*pr[j]]=1;
    			if(i%pr[j]==0)break;
    		}
    	}
    }
    inline bool Miller_Rabin(ll x){
    	ll mod=x;
    	if(x<=M)return !isp[x];
    	if(!(x&1))return false;
    	if((x%3==0)||(x%5==0)||(x%7==0))return false;
    	ll t=x-1,s=0;
    	while(!(t&1))t>>=1,s++;
    	for(int i=1;i<=20&&pr[i]<x;i++){
    		ll k=ksm(pr[i],t,mod),pre=k;
    		if(x%pr[i]==0)return false;
    		for(int j=0;j<s;j++){
    			k=mul(k,k,mod);
    			if(k==1&&pre!=1&&pre!=x-1)return false;
    			pre=k;
    		}
    		if(k!=1)return false;
    	}
    	return true;
    }
    int c[N],ans,cnt;
    inline void calc(int coef,int coef2,int siz){
    	if(siz&1)Add(ans,mul(coef2,ksm(2,coef)-1));
    	else Dec(ans,mul(coef2,ksm(2,coef)-1));
    }
    void dfs(int pos,int coef,int coef2,int siz){
    	if(pos==cnt+1)return calc(coef,coef2,siz);
    	dfs(pos+1,mul(coef,c[pos]+1,mod-1),coef2,siz);
    	dfs(pos+1,mul(coef,c[pos],mod-1),mul(coef2,2),siz+1);
    	if(c[pos]>1)dfs(pos+1,mul(coef,c[pos]-1,mod-1),coef2,siz+2);
    }
    int main(){
    	init();
    	ll m;
    	scanf("%lld",&m);
    	for(int i=1;i<=tot;i++){
    		if(m%pr[i]==0){
    			int tt=0;
    			while(m%pr[i]==0)tt++,m/=pr[i];
    			c[++cnt]=tt;
    		}
    	}
    	if(m>1){
    		if(Miller_Rabin(m))c[++cnt]=1;
    		else{
    			int x=sqrt(m);
    			if(1ll*x*x==m){
    				c[++cnt]=2;
    			}
    			else{
    				c[++cnt]=1,c[++cnt]=1;
    			}
    		}
    	}
    	dfs(1,1,1,1);
    	cout<<ans;
    }
    

    T2

    kik_iii个选的个数,f[i][j][k]f[i][j][k]表示前ii个,填了jj个,amax(0,caka)max(0,kaca)/4=ksum_amax(0,c_a-k_a)-max(0,k_a-c_a)/4=k的方案数,步长乘方案数就是答案

    最后由于去重是(ki)!ki!frac{(sum k_i)!}{prod k_i!}
    下面的系数中间边乘维护

    边界情况有点奇怪,反正我是没搞懂

    #include<bits/stdc++.h>
    using namespace std;
    #define gc getchar
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    #define re register
    #define pb push_back
    #define cs const
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define ll long long
    #define poly vector<int>
    #define bg begin
    cs int mod=1e9+7;
    inline int ksm(int a,int b,int res=1){
    	for(;b;b>>=1,a=1ll*a*a%mod)(b&1)&&(res=1ll*res*a%mod);return res;
    }
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=12,M=405,C=1605;
    int f[N][M][C],q[N],c[N],p[C],fac[C],ifac[C],Q,tot,mx,n;
    inline void init(){
    	fac[0]=ifac[0]=1;
    	for(int i=1;i<C;i++)fac[i]=1ll*fac[i-1]*i%mod;
    	ifac[C-1]=ksm(fac[C-1],mod-2);
    	for(int i=C-2;i;i--)ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
    }
    int main(){
    	init();
    	n=read();
    	for(int i=1;i<=n;i++)q[i]=read(),Q+=q[i];
    	Q=ksm(Q,mod-2);
    	for(int i=1;i<=n;i++)q[i]=1ll*q[i]*Q%mod;
    	for(int i=1;i<=n;i++)c[i]=read(),tot+=c[i];
    	f[0][tot][0]=1,mx=tot*4;
    	for(int i=1;i<=n;i++){
    		for(int t=1,j=0;j<=mx;j++,(t=1ll*t*q[i]%mod))p[j]=1ll*ifac[j]*t%mod;
    		for(int j=0;j<=tot;j++)for(int k=0;k<=mx;k++)
    		if(f[i-1][j][k]){
    			int pt=f[i-1][j][k];
    			for(int l=0;l<=mx-k;l++){
    				int del=c[i];
    				if(l<c[i])del+=l-c[i];
    				else del+=(l-c[i])/4;
    				if(j>=del)(f[i][j-del][k+l]+=1ll*pt*p[l]%mod)%=mod;
    			}
    		}
    	}
    	int res=1;
    	for(int j=1;j<=mx;j++){
    		int now=0;
    		for(int i=1;i<=tot;i++)
    		(now+=f[n][i][j])%=mod;
    		(res+=1ll*fac[j]*now%mod)%=mod;
    	}
    	cout<<res;
    }
    

    T3

    考场用随机化贪心骗了45pts45pts

    实际上把式子拆开
    可以发现我们只需要把两两点匹配使得点积和最大

    这是一个二分图最大权匹配
    结果卡了费用流做法。。。。

    只能写KMKM,还只有非递归版能过

    OrzOrz了一波仲爺的板子

    #include<bits/stdc++.h>
    using namespace std;
    #define gc getchar
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    #define re register
    #define pb push_back
    #define cs const
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define ll long long
    #define poly vector<int>
    #define bg begin
    cs int mod=998244353;
    inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
    inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
    inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
    inline void Dec(int &a,int b){(a-=b)<0?(a+=mod):0;}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline int mul(int a,int b,int Mod){return 1ll*a*b>=Mod?1ll*a*b%Mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b,int res=1){
    	for(;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));return res;
    }
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=505;
    int a[N][N],n;
    namespace KM{
    	int wx[N],wy[N],px[N],py[N],vx[N],vy[N],path[N],id,mn[N];
    	#define calc(x,y) ((wx[(x)]+wy[(y)]-a[(x)][(y)]))
    	inline void solve(){
    		for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)chemx(wx[i],a[i][j]);
    		for(int i=1;i<=n;i++){
    			vx[i]=++id,path[i]=0;
    			for(int j=1;j<=n;j++)mn[j]=i;
    			while(!px[i]){
    				int oy=0;
    				for(int j=1;j<=n;j++)
    				if(vy[j]!=id&&(!oy||(calc(mn[j],j)<calc(mn[oy],oy))))oy=j;
    				int ox=mn[oy],val=calc(ox,oy);
    				for(int j=1;j<=n;j++){
    					if(vx[j]==id)wx[j]-=val;
    					if(vy[j]==id)wy[j]+=val;
    				}
    				if(!py[oy]){
    					while(ox){
    						py[oy]=ox;
    						swap(oy,px[ox]);
    						ox=path[ox];
    					}
    				}
    				else{
    					int curx=py[oy];path[curx]=ox;
    					vx[curx]=vy[oy]=id;
    					for(int j=1;j<=n;j++)
    					if(vy[j]!=id&&(calc(mn[j],j))>calc(curx,j))mn[j]=curx;
    				}
    			}
    		}
    		cout<<"Yes
    ";
    		for(int i=1;i<=n;i++)cout<<px[i]<<" ";
    	}
    }
    struct pt{
    	int x,y;
    	pt(int _x=0,int _y=0):x(_x),y(_y){}
    	friend inline int operator ^(cs pt &a,cs pt &b){
    		return a.x*b.x+a.y*b.y;
    	}
    }p[N],v[N];
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++)p[i].x=read(),p[i].y=read();
    	for(int i=1;i<=n;i++)v[i].x=read(),v[i].y=read();
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)a[i][j]=p[i]^v[j];
    	KM::solve();
    }
    
  • 相关阅读:
    二元关系最小割
    DG观察日志传输
    [WC2007]剪刀石头布——费用流
    备库报 ORA-00313、ORA-00312、ORA-27037
    「清华集训 2017」无限之环
    The listener supports no services
    [SDOI2010]星际竞速——费用流
    ORA-16055: FAL request rejected
    [总结]网络流
    ORA-16047: DGID mismatch between destination setting and standby
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328669.html
Copyright © 2020-2023  润新知