zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 116

    A

    (n) 质因数分解为 (prodlimits_{i=1}^m p_i^{c_i}),那么奇数因子的个数为 (prodlimits_{1le ile moperatorname{and}p_i ot=2} c_i+1),偶数因子个数为 (c'cdotprodlimits_{1le ile moperatorname{and}p_i ot=2} c_i+1)(c') 为质因子 (2) 的指数,算一下 (c') 的大小即可。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    		ll n;
    		scanf("%lld",&n);
    		if(n%2==0&&n%4!=0) puts("Same");
    		else if(n&1ll) puts("Odd");
    		else puts("Even");
    	}
    	return 0;
    }
    

    B

    套路题。

    先 sort 一遍。从 (a_1)(a_n) 枚举 (max(B)),此时能够当作 (min(B)) 的只有这个数及它之前的数。假设当前枚举到的数是 (a_i),钦定一个数 (a_j)(j<i))为 (min(B))(对于 (min(B)=max(B)) 的情况单独计算即可),那么以 (a_i)(max),以 (a_j)(min) 的子序列共 (2^{i-j-1}) 个,也就是说能够给答案带来 (2^{i-j-1}a_ia_j) 的贡献,写成式子就是:

    [sumlimits_{i=1}^nleft(a_isumlimits_{j=1}^{i-1}2^{i-j-1}a_j ight)+sumlimits_{i=1}^n a_i^2 ]

    枚举到 (i-1) 的时候实际上已经计算了 (sumlimits_{j=1}^{i-2}2^{i-j-2}a_j),所以到 (i) 时无需重新计算,直接 ( imes 2+a_{i-1}) 即可。

    时间复杂度为 (mathcal O(nlog n))(排序的复杂度)。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define int long long
    inline void read(int &x)
    {
    	x=0;int f=1;
    	char c=getchar();
    	while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	x*=f; 
    }
    const int N=2e5+10;
    int a[N];
    signed main()
    {
    	int n;read(n);
    	for(int i=1;i<=n;i++)read(a[i]);
    	sort(a+1,a+n+1);
    	int sum=0,ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		sum=(sum*2+a[i-1])%998244353;
    		ans+=a[i]*(a[i]+sum);ans%=998244353;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    

    C

    非常有意思的一道题,感谢 这篇题解

    因为 (min{lfloorlog_2m floor,n}le 18),所以不同的数不会超过 (18) 个,记为 (p)。假设我们已经知道了选哪 (k) 个数,那么给答案的贡献就是 (mathrm C_{n-1}^{k-1}),也就是 (n) 个位置分给 (k) 个数的方案数(隔板法)。如果知道选择 (k) 个数的方案数 (sigma_i),那么答案就是 (sumlimits_{i=1}^{p} sigma_imathrm C_{n-1}^{i-1}),问题就转化成了:选 (k) 个值域在 ([1,m]) 内的不同的数,求方案数。令 (f(i,j)) 表示当第 (j) 个数的值为 (i) 的方案数,那么可以进行主动更新 (f(ik,j+1)gets f(ik,j+1)+f(i,j);(kge2,ikle m)),这样就可以得到 (sigma_i=sumlimits_{j=1}^m f(j,i)),问题解决。

    总结:问题的突破口在于发现「所以不同的数不会超过 (18) 个」,此类问题的关键点是需要找到这些较小的值或者特殊性质,无思路是多观察这些东西。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int N=2e5+10;
    int p[N],inv[N];
    int C(int n,int m) {return (long long)p[n]*inv[m]%998244353*inv[n-m]%998244353;}
    int qpow(int a,int n)
    {
    	a%=998244353;
    	int ans=1;
    	while(n)
    	{
    		if(n&1) ans=(long long)ans*a%998244353;
    		a=(long long)a*a%998244353;
    		n>>=1;
    	}
    	return ans;
    }
    int sum[N],f[N][30];
    int main()
    {
    	int n,m;
    	scanf("%d%d",&n,&m);
    	p[0]=inv[0]=1;
    	for(int i=1;i<=n;i++) 
    	{
    		p[i]=(long long)p[i-1]*i%998244353;
    		inv[i]=qpow(p[i],998244351);
    	}
    	int p=min((int)(log(m)/log(2))+1,n);
    	for(int i=1;i<=m;i++) f[i][1]=1;
    	for(int i=1;i<=m;i++)
    	{
    		for(int j=1;j<=p;j++)
    		{
    			for(int k=2;k*i<=m;k++)
    			{
    				f[k*i][j+1]+=f[i][j];
    				f[k*i][j+1]%=998244353;
    			}
    		}
    	}
    	for(int i=1;i<=p;i++)
    	{ 
    		for(int j=1;j<=m;j++)
    		{
    			sum[i]+=f[j][i];
    			sum[i]%=998244353;
    		}
    	}
    	int ans=0;
    	for(int i=1;i<=p;i++)
    	{
    		ans+=(long long)C(n-1,i-1)*sum[i]%998244353;
    		ans%=998244353;
    	}
    	printf("%d",ans);
    	return 0; 
    }
    

    D

    由于异或和为 (0),所以每一位中 (1) 的出现次数都是偶数。可以转化成模型:现在有 (log_2 m) 个组,第 (i) 组((0le ile log_2 m))的物品体积为 (2cdot2^i,4cdot2^i,6cdot 2^i,cdots,2kcdot 2^i)(k) 是正整数,(2kcdot 2^ile m)),问有多少种方案能够凑出 (m)。假设我们在这一组取的物品为 (2k'cdot 2^i),那么分给 (n) 个数就有 (mathrm C_n^{2k'})(n) 个位置选 (2k') 个)选法,即如果令 (f(j)) 表示凑出 (j) 的方案数,则有:

    [f(j)gets f(j)+mathrm C_{n}^{2k}f(j-2kcdot 2^i) ]

    复杂度在 (mathcal O(nlog n)) 级别。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=5010;
    int qpow(int a,int n)
    {
    	int ans=1;
    	while(n)
    	{
    		if(n&1) ans=(long long)ans*a%998244353;
    		a=(long long)a*a%998244353;
    		n>>=1;
    	}
    	return ans;
    }
    int f[N],p[N],inv[N];
    int C(int n,int m) {return (long long)p[n]*inv[m]%998244353*inv[n-m]%998244353;}
    int main()
    {
    	int n,m;
    	scanf("%d%d",&n,&m);
    	p[0]=inv[0]=1;
    	for(int i=1;i<=n;i++)
    	{
    		p[i]=(long long)p[i-1]*i%998244353;
    		inv[i]=qpow(p[i],998244351);
    	}
    	f[0]=1;
    	for(int i=0;(1<<i)<=m;i++)
    		for(int j=m;j>=0;j--)
    			for(int k=1;2*k*(1<<i)<=j;k++)
    				if(j-2*k*(1<<i)>=0)
    				{ 
    					f[j]+=(long long)f[j-2*k*(1<<i)]*C(n,2*k)%998244353;
    					f[j]%=998244353;
    				}
    	printf("%d",f[m]);
    	return 0;
    }
    
  • 相关阅读:
    struts2_maven_learning
    test_maven_实现表单验证
    Struts2_learning
    计算机信息安全技术_学习
    SQL_sql语言的学习
    ios视图加载时所涉及到的事件
    ios 判断版本更新
    ios 裁剪图片(1裁多)
    iOS 设置与配置
    ios Auto Layout中Stack View的使用
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/14604292.html
Copyright © 2011-2022 走看看