zoukankan      html  css  js  c++  java
  • AtCoder Grand Contest 043B(组合数学)

    先进行一次绝对值差分,把序列中的数都变成 0,1,2 。如果序列中存在 1,答案只能是 0 或 1;如果不存在 1,答案只能是 0 或 2。对于不存在 1 的情况,我们可以将每个数都 除以2,最后再将答案 乘2,这显然是等价的。于是现在答案只能是 0 或 1 ,发现绝对值差分等价于异或。现在问题转化为一个 只包含0和1的序列,每次将相邻两个数异或,求最后剩下的数。那么考虑每个数会被异或几次即可,设序列长度为 n,则位置 i 上的数会被异或 (n−1,i−1) 次。这时候我们还要求出模 2 意义下的组合数,一个简单的方法是计算每个阶乘的分解中 2 的次数,将计算组合数时的除法改为做减法。则对于一个组合数,最后如果剩下的 2 的次数为 0,则说明 mod2=1,否则 mod2=0。对于阶乘的分解,可以先对每个数简单地求出分解中 2 的次数,然后做前缀和即可。时间复杂度 O(n)。

     1 #define HAVE_STRUCT_TIMESPEC
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 int a[1000007],c[1000007];
     5 char s[1000007];
     6 int main() {
     7     ios::sync_with_stdio(false);
     8     cin.tie(NULL);
     9     cout.tie(NULL);
    10     int n;
    11     cin>>n;
    12     cin>>s+1;
    13     --n;
    14     for(int i=1;i<=n;++i)
    15         a[i]=abs(s[i]-s[i+1]);
    16     int flag=0;
    17     for(int i=1;i<=n;++i)
    18         if(a[i]==1)
    19             flag=1;
    20     if(!flag)
    21         for(int i=1;i<=n;++i)
    22             a[i]>>=1;
    23     for(int i=1;i<=n;++i){
    24         int x=i;
    25         while(!(x&1))
    26             ++c[i],x>>=1;
    27         c[i]+=c[i-1];
    28     }
    29     int ans=0;
    30     for(int i=1;i<=n;++i)
    31         ans^=c[n-1]-c[i-1]-c[n-i]?0:(a[i]&1);
    32     if(!flag)
    33         ans<<=1;
    34     cout<<ans;
    35     return 0;
    36 }
  • 相关阅读:
    Linux下MySql多实例免安装部署
    linux apf防火墙安装配置
    Fedora Yum命令查询软件包及清除缓存
    什么时候使用e.target.content和e.target as MovieClip
    帧频计数器
    设置播放器的品质
    访问文件名连续的mc、txt、btn
    Sound 音乐工具类【转载】
    确定字符串中、出现特定字符串的次数
    数组var _list:Array = new Array({logType:"1"});
  • 原文地址:https://www.cnblogs.com/ldudxy/p/12601250.html
Copyright © 2011-2022 走看看