zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 116(A-D)

    A、Odd vs Even

    • editorial

      已知对于给定数字(n),他的因子可以表示成(prodlimits_{i=1}^{m}p_i^{cnt_i}),其中(p_i)是n的素因子,(cnt_i in [0,a_i]), (a_i)是满足([n mod p_i^{a_i} = 0])这个条件的最大值。

      故知若(2^{a_i})中的(a_i)大于1时,偶因子多于奇因子个数;两者相等时,偶因子等于奇因子个数;否则,偶因子少于奇因子个数。

    • code

      #include<bits/stdc++.h>
      using namespace std;
      
      typedef long long ll;
      int main()
      {
          int t;
          scanf("%d", &t);
          while(t--)
          {
              ll n;
              scanf("%lld", &n);
              if(n % 4 == 0)
                  puts("Even");
              else if(n % 2 == 0 )
                  puts("Same");
              else
                  puts("Odd");
          }
          return 0;
      }
      

    B、Products of Min-Max

    • editorial

      首先我们对该序列进行排序,发现就可以固定两端,中间是否选择,共有(2^{max(0,j-i+1)})中选择,故答案为

      [sumlimits_{i=1}^nsumlimits_{j=i}^na_i*a_j*2^{max(0,j-i-1)}=sumlimits_{i=1}^na_i*sumlimits_{j=i}^na_j*2^{max(0,j-i-1)} =sumlimits_{i=1}^na_i*sumlimits_{j=i+1}^na_j*2^{j-i-1}+sumlimits_{i=1}^na_i^2 ]

      观察式子发现

      (sumlimits_{j=i}a_j*2^{j-i}=2*sumlimits_{j=i+1}a_j*2^{j-i}+a_i)

      故我们从后往前计算。

    • code

      #include<bits/stdc++.h>
      using namespace std;
      typedef long long ll;
      const int NMAX = 2e5 + 10;
      const int MOD = 998244353;
       
      int a[NMAX];
      int main()
      {
          int n;
          scanf("%d", &n);
          ll ans = 0, ant;
          for(int i = 1;i <= n;i++)   
          {
              scanf("%d", a + i);
              ans = (ans + 1ll*a[i]*a[i]%MOD)%MOD;
          }
          sort(a + 1, a + 1 + n);
          ant = a[n];
          for(int i = n-1;i >= 1;i--)
          {
              ans = (ans + ant*a[i]%MOD)%MOD;
              ant = (ant*2%MOD + a[i])%MOD;
          }
          printf("%lld
      ", ans);
          return 0;
      }
      

    C、Multiple Sequences

    • editorial

      对于整数(m),连续的因子序列(因子序列中元素互不相等),最大长度为(lfloorlog_2m floor),故进行dp,(dp[i][j])表示最后一位数字,当前序列长度为(i)的可能情况。

      而对于原问题的序列我们可以通过我们的序列进行扩展,即将长度为(i)的序列扩展成长度为(n),即可以想象把长度为(n)的序列划分为(i)段,用插空法求出有((n-1,i-1))种方式,故答案为(sumlimits_{i=1}^{20}(n-1,i-1)*(sumlimits_{j=1}^mdp[i][j]))

    • code

      #include<bits/stdc++.h>
       
      using namespace std;
      const int NMAX = 2e5 + 10;
      const int MOD = 998244353;
      typedef long long ll;
       
      ll dp[20][NMAX], sum[20];
      ll f[NMAX],finv[NMAX];
      ll fast_pow(ll a,ll n)
      {
          ll ans = 1;
          while(n)
          {
              if(n&1) ans = (ans * a)%MOD;
              a = (a * a)%MOD;
              n >>= 1;
          }
          return ans;
      }
      ll C(ll n,ll m)
      {
      	return (n<0||m<0||n<m)?0:f[n]*(finv[m])%mod*finv[n-m]%mod;
      }
      void init()
      {
          f[0]=1;
          for(int i=1;i< NMAX;i++)
              f[i]=f[i-1]*i%mod;
          finv[NMAX-1] = fast_pow(f[NMAX-1],mod-2);
          for (int i=NMAX-1; i > 0; i--)
              finv[i-1]=finv[i]*i%mod;
      }	
      int main()
      {
          int n, m;
          init();
          scanf("%d%d", &n, &m);
          for(int i = 1;i <= m;i++)   dp[1][i] = 1;
          sum[1] = m%MOD;
          for(int j = 2;j < 20;j++)
          {
              for(int i = 1;i <= m;i++)
                  for(int k = 2*i; k <= m;k += i)
                      dp[j][k] = (dp[j][k] + dp[j-1][i])%MOD;
              for(int i = 1;i <= m;i++)
                  sum[j] = (sum[j] + dp[j][i])%MOD;
          }
          
          ll ans = 0;        
          for(int i = 1;i < 20;i++)
              ans = (ans + C(n-1, i-1)*sum[i]%MOD)%MOD;  
          printf("%lld
      ", ans);
          return 0;
      }
      

    D、Wanna Win The Game

    • editorial
      官方题解
      (sum A_i)为偶数时,(Xor A_i)才可能存在情况数,对于所有的(A_i)二进制,固定位的(1)的个数必然为偶数。那我们从低位往高位开始,构造序列(A)
      定义(dp[i])(m=i)的答案,首先构造最后一位,即对于偶数(m),将(m)(1)放到(n)个位置(保证一个位置至多只有一个一),共有((n, m))中方案。用之前的方案数来更新当前的情况,即在原来的序列每个元素左移一位,然后选择(2j)(1),分别加到序列(A)中,故有转移方程如下:

    [ dp[i*2+j] = 1ll*(dp[(i<<1)+j] + 1ll*dp[i]*C[n][j] mod MOD) mod MOD iff jequiv0pmod{2} ]

    • code

      #include <bits/stdc++.h>
      using namespace std;
      
      const int MOD = 998244353;
      const int NMAX = 5e3 + 5;
      
      typedef long long ll;
      
      int C[NMAX][NMAX];
      int dp[NMAX];
      void init()
      {
          C[0][0] = 1;
          for(int i = 1;i < NMAX;i++)
          {
              C[i][0] = 1;
              for(int j = 1;j <= i;j++)
                  C[i][j] = (C[i-1][j] + C[i-1][j-1])%MOD;
          }
      }
      
      int main()
      {
          init();
          int n, m;
          scanf("%d%d", &n, &m);
          for(int i = 2;i <= m;i += 2)
              dp[i] = C[n][i];
          for(int i = 1;i <= m;i++)
              for(int j = 0;(i<<1)+j <= m;j += 2)
                  dp[i*2+j] = 1ll*(dp[(i<<1)+j] + 1ll*dp[i]*C[n][j]%MOD)%MOD;
          printf("%d
      ", dp[m]);
          return 0;
      }
      
  • 相关阅读:
    暗时间:学习的精神和方法
    林布蘭
    魯本斯
    維梅爾
    哈爾斯.法蘭斯
    SAFEARRAY使用方法示例
    范戴克
    100个经典错别字
    在CPP中调用Jscript中的函数
    生活在真空中的程序员
  • 原文地址:https://www.cnblogs.com/lemon-jade/p/14595311.html
Copyright © 2011-2022 走看看