zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 114(A-C)

    A - Not coprime

    题意:已知(N)个数字不超过50,找到最小的数字与这(N)个数字不互素
    题解:知(1-50)的素数一共有15个,故答案一定是这15个素数组合的乘积。故枚举这些组合。
    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
     
    typedef long long ll;
    const int NMAX = 2e5 + 10;
    const int MOD = 1e9 + 7;
     
    int a[50];
    int prime[50], isw[50], tot;
    void init()
    {
    	for(int i = 2;i < 50;i++)
    	{
    		if(!isw[i])  prime[++tot] = i;
                    for(int j = 1;j <= tot;j++){
                        if(i * prime[j] >= 50)    break;
                        isw[i*prime[j]] = 1;
                        if(i % prime[j] == 0)   break;
                    }
    	}
    }
    int main(int argc, char const *argv[])
    {
    	int n;
    	init();
    	scanf("%d",&n);
    	for(int i = 1;i <= n;i++)
    		scanf("%d", a+i);
    	ll ans = (1ll<<63)-1, ant;
    	for(int i = 1;i < 1<<15;i++)
    	{
    		bool flag = true;
    		ant = 1ll;
    		for(int j = 0;j < 15;j++)
    			if((i>>j) & 1)
    				ant *= prime[j+1];
    		for(int j = 1;flag && j <= n;j++)
    			if(__gcd(1ll*a[j], ant) == 1ll)
    				flag = false;
    		if(flag)
    			ans = min(ans, ant);
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    B - Special Subsets

    题意:寻找满足条件的集合个数。
    题解:找环的个数(cyc),答案为(2^{cyc}-1)
    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
     
    typedef long long ll;
    const int NMAX = 2e5 + 10;
    const int MOD = 998244353;
    int vis[NMAX], num, ant,nxt[NMAX];
    void dfs(int x)
    {
    	if(vis[x])
    	{
    		if(vis[x] == ant)	num++;
    		return;
    	}
    	vis[x] = ant;
    	dfs(nxt[x]);
    }
     
    ll fast_pow(ll a, int n)
    {
    	ll ans = 1;
     
    	while(n)
    	{
    		if(n & 1) ans = ans * a % MOD;
    		a = a * a %MOD;
    		n >>= 1;
    	}
    	return ans;
    }
    int main(int argc, char const *argv[])
    {
    	int n;
    	scanf("%d", &n);
    	for(int i  = 1;i <= n;i++)
    		scanf("%d", nxt + i);
    	num = 0;
    	for(int i = 1;i <= n;i++)
    	{
    		ant++;
    		if(!vis[i])
    			dfs(i);
    	}
    	printf("%lld
    ", (fast_pow(2ll, num) - 1 + MOD)%MOD );
    	return 0;
    }
    

    C - Sequence Scores

    题意:一共有(N)个位置,有(1-M)的数字可以填写到这(N)个位置上,形成一个序列(A),求所有序列(A)(f(A))的和,其中(f(A))表示从序列(X=[0,...,0])到序列(A)操作个数,操作是选定一个区间([l,r])(v)使得(X_i)(max(X_i, v))

    题解

    官方题解
    对于固定序列(A),(f(A))为图的联通分量个数,若$$i<j iff A_i = A_j, exists i<k<j 使得 A_k<A_i$$则(<i,j>)是联通的。对于一个序列(A)最坏情况需要的操作步数是(N),所以所有的序列最坏操作步数总和是(ans = N cdot M^N),固定(<i,j>),保证(A_i = A_j),区间((i,j))的值都大于(A_i)的个数有(ant = sumlimits_{i=1}^{N}sumlimits_{j=i+1}^{N}(sumlimits_{x=1}^{M}(M-x)^{j-i-1})cdot M^{N-(j-i+1)}),这样操作会使(<i,j>)联通,使得(i,j)的操作数减少一,还有对于邻近位置相等的数时也会使得操作数减少一,对于临近位置相等的数的操作步数,我们可以设置(0^0=1),那么ant将包含该操作数。故答案应为(ans - ant)。其中(j-i)(x)可以确定,故时间复杂度为(O(N cdot M)), 本文写的代码写了fast_pow(),可以预处理。
    代码如下:

    #include <bits/stdc++.h>
     
    using namespace std;
    typedef long long ll;
    const int NMAX = 5003;
    const int MOD = 998244353;
     
    ll m_pow[NMAX];
     
    ll fast_pow(ll a, int n)
    {
    	ll ans = 1;
    	while(n)
    	{
    		if(n & 1)	ans = ans * a % MOD;
    		a = a * a % MOD;
    		n >>= 1;	
    	}
    	return ans;
    }
    int main()
    {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	m_pow[0] = 1;
    	for(int i = 1;i < n;i++)
    		m_pow[i] = m*m_pow[i-1] % MOD;
    	ll ans = 0;
    	for(int j_i = 1;j_i < n;j_i++)
    	{
    		ll ant = 0;
    		for(int x = 1;x <= m;x++)
    			ant = (ant + fast_pow(m-x, j_i-1))%MOD;
    		ans = (ans + ant*m_pow[n-j_i-1]%MOD*(n-j_i)%MOD)%MOD;
    	}
    	ans = (1ll*n*fast_pow(m, n)%MOD - ans + MOD)%MOD; 
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    工具链中 Binutils的内容
    Qt 4.5 新功能逐一看 – 性能优化
    qt 打不开 用于触摸屏校准的文件
    Unicode 编码范围
    Android OpenGL ES 分析与实践
    Armlinux GCC 交叉编译工具
    二维矢量图形算法加速标准 OpenVG
    电路和程序一样,不是设计出来的,是调出来的
    电子元件又一话电容篇
    TVS管
  • 原文地址:https://www.cnblogs.com/lemon-jade/p/14540505.html
Copyright © 2011-2022 走看看