zoukankan      html  css  js  c++  java
  • Tenka1 Programmer Contest 2019

    A.一定是前半段白后半段黑,枚举分界点预处理前后缀和。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     6 typedef long long ll;
     7 using namespace std;
     8 
     9 const int N=200010;
    10 char s[N];
    11 int n,ans,pre[N],suf[N];
    12 
    13 int main(){
    14     freopen("a.in","r",stdin);
    15     freopen("a.out","w",stdout);
    16     scanf("%d%s",&n,s+1); ans=n+1;
    17     rep(i,1,n) pre[i]=pre[i-1]+(s[i]=='#');
    18     for (int i=n; i; i--) suf[i]=suf[i+1]+(s[i]=='.');
    19     rep(i,0,n) ans=min(ans,pre[i]+suf[i+1]);
    20     printf("%d
    ",ans);
    21     return 0;
    22 }
    A

    B.总数-存在某个集合超过总和一半的方案数,先默认这个大集合是R最后再乘3。

    f[i][j]表示前i个数中R中数之和为j,不在R中的数随意放入G和B的方案数。发现这样可能会多考虑空集,于是再令g[i][j]表示前i个数中R中数和为j,不在R中的数全部放入G的方案数,做个类似的DP即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     6 typedef long long ll;
     7 using namespace std;
     8 
     9 const int N=310,mod=998244353;
    10 int n,ans,sm,a[N],f[N*N],g[N*N];
    11 
    12 int ksm(int a,int b){
    13     int res=1;
    14     for (; b; a=1ll*a*a%mod,b>>=1)
    15         if (b & 1) res=1ll*res*a%mod;
    16     return res;
    17 }
    18 
    19 int main(){
    20     freopen("b.in","r",stdin);
    21     freopen("b.out","w",stdout);
    22     scanf("%d",&n); ans=(ksm(3,n)-3ll*ksm(2,n)+3+3ll*mod)%mod;
    23     rep(i,1,n) scanf("%d",&a[i]),sm+=a[i];
    24     f[0]=g[0]=1;
    25     rep(i,1,n) for (int j=sm; ~j; j--){
    26         f[j]=(f[j]*2ll+(j>=a[i]?f[j-a[i]]:0))%mod;
    27         g[j]=(g[j]+(j>=a[i]?g[j-a[i]]:0))%mod;
    28     }
    29     rep(i,(sm+1)/2,sm-1) ans=(ans-3ll*(f[i]-2ll*g[i])+3ll*mod)%mod;
    30     printf("%d
    ",ans);
    31     return 0;
    32 }
    B

    C.结论:p能成为答案,当且仅当:p是所有系数gcd的质因子,或(x^p-x)能整除原多项式。

    第一种情况由裴蜀定理知显然。第二种情况我是这样理解的:若两个多项式次数相同且所有根都相同,那么它们就是同一个多项式,在模意义下或许同样如此。那么由于1~p-1全部为原多项式的根,也就是x(x-1)(x-2)...(x-p+1)能整除原式。而这个式子和(x^p-x)在模p意义下是相等的,于是直接判断(x^p-x)能否整除原式即可。

    下面考虑如何判断(x^n-1)是否整除一个多项式,发现只要判断“所有%n同余的次数项的系数之和是否全为0”即可。总复杂度O(n^2)。

     1 #include<set>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=200010;
     9 int n,m,a[N],h[N];
    10 set<int>ans;
    11 
    12 void chk(int p){
    13     rep(i,0,p-2) h[i]=0;
    14     rep(i,0,n) h[i%(p-1)]=(h[i%(p-1)]+a[i])%p;
    15     rep(i,0,p-2) if (h[i]) return;
    16     ans.insert(p);
    17 }
    18 
    19 int main(){
    20     freopen("c.in","r",stdin);
    21     freopen("c.out","w",stdout);
    22     scanf("%d",&n);
    23     for (int i=n; ~i; i--) scanf("%d",&a[i]),m=__gcd(m,abs(a[i]));
    24     for (int i=2; i*i<=m; i++) if (m%i==0){
    25         ans.insert(i);
    26         while (m%i==0) m/=i;
    27     }
    28     if (m!=1) ans.insert(m);
    29     rep(i,2,n) if (a[0]%i==0){
    30         bool flag=1;
    31         for (int j=2; j*j<=i; j++) if (i%j==0){ flag=0; break; }
    32         if (flag) chk(i);
    33     }
    34     for (set<int>::iterator it=ans.begin(); it!=ans.end(); it++) printf("%d
    ",*it);
    35     return 0;
    36 }
    C
  • 相关阅读:
    A1052. Linked List Sorting (25)
    A1032. Sharing (25)
    A1022. Digital Library (30)
    A1071. Speech Patterns (25)
    A1054. The Dominant Color (20)
    A1060. Are They Equal (25)
    A1063. Set Similarity (25)
    电子码表
    矩阵键盘
    对象追踪、临时对象追踪、绝对坐标与相对坐标
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10752829.html
Copyright © 2011-2022 走看看