zoukankan      html  css  js  c++  java
  • 【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();
    }
    
  • 相关阅读:
    4.计算机启动过程的简单介绍 计算机启动流程 计算机BIOS作用 POST 开机自检 计算机启动顺序 分区表 操作系统启动
    3.操作系统简单介绍 操作系统发展历史 批处理分时系统 操作系统是什么 操作系统对文件的抽象 进程 虚拟内存是什么 操作系统作用 操作系统功能
    2.计算机组成-数字逻辑电路 门电路与半加器 异或运算半加器 全加器组成 全加器结构 反馈电路 振荡器 存储 D T 触发器 循环移位 计数器 寄存器 传输门电路 译码器 晶体管 sram rom 微处理 计算机
    1.计算机发展阶段 计算机发展历史 机械式计算机 机电式计算机 电子计算机 逻辑电路与计算机 二极管 电子管 晶体管 硅 门电路 计算机 电磁学计算机二进制
    如何解决svn清理失败 不能更新 cleanup失败 cleanup乱码 更新乱码 svn更新提示清理 清理乱码不能清理 svn故障修复SVN cleanup 陷入死循环 svn cleanup时遇到错误怎么办
    eclipse svn插件卸载 重新安装 Subclipse卸载安装 The project was not built since its build path is incomplete This client is too old to work with the working copy at
    java for循环里面执行sql语句操作,有效结果只有一次,只执行了一次sql mybatis 循环执行update生效一次 实际只执行一次
    windows资源管理器多标签打开 windows文件夹多标签浏览 浏览器tab页面一样浏览文件夹 clover win8 win10 报错 无响应问题怎么解决 clover卡死 clover怎么换皮肤
    批处理启动vm虚拟机服务 vm12启动无界面启动vm虚拟机系统 windows上如何操作服务 sc net启动关闭服务
    不能ssh连接ubuntu linux 服务器 secureCRT不能ssh连接服务器 不能远程ssh连接虚拟机的ubuntu linux
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328670.html
Copyright © 2011-2022 走看看