首页 > 其他分享 >黎明前的巧克力

黎明前的巧克力

时间:2023-04-25 20:22:57浏览次数:35  
标签:黎明前 cnt int 巧克力 异或 ans dp mod

刚考完省选回来的时候搬的模拟赛的题。看到一道长的很类似的题所以把题解蒯过来。

首先对于每个异或和为 \(0\) 的子集 \(T\),贡献为 \(2^{|T|}\)。答案就是把他们加起来然后减掉 \(1\),是两个都不选的。

那么有一个浅显的 dp:\(dp_{i,j}\) 为考虑前 \(i\) 个元素,异或和为 \(j\) 的贡献和,那么转移:

\[dp_{i,j}=dp_{i-1,j}+dp_{i-1,j\oplus a_i} \]

若设 \(F_i\) 为 \(dp_i\) 的集合幂级数,则有

\[F_i=F_{i-1}\times(x^{\varnothing}+2x^{a_i}) \]

\(\times\) 为异或卷积。

此时我们把答案写成了异或卷积的形式。考虑 \(\text{FWT}(x^{\varnothing}+2x^{a_i})_j\) 的值,根据定义可以得到是:

\[\text{FWT}(x^{\varnothing}+2x^{a_i})_j= \begin{cases} -1\qquad &(|a_i\cap j|\bmod 2=1)\\ 3 &(|a_i\cap j|\bmod 2=0) \end{cases} \]

那么只要算一下 \(a_i\cap j\bmod 2=1\) 的个数,随便统计一下就行了。

转化一下,设 \(cnt_i\) 为 \(i\) 的个数,那么可以直接求 \(\sum_{i}(-1)^{i\cap j}b_j\) 然后解方程得到个数。只需要一次 FWT。

#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int mod=998244353;
int n,ans,a[1<<20],pw[1<<20];
int qpow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=1ll*ans*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return ans;
}
void fwt(int a[],int n){
    for(int mid=1;mid<n;mid<<=1){
        for(int i=0;i<n;i+=mid<<1){
            for(int j=0;j<mid;j++){
                int x=a[i+j],y=a[i+j+mid];
                a[i+j]=x+y;a[i+j+mid]=x-y;
            }
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int x;scanf("%d",&x);a[x]++;
    }
    pw[0]=1;
    for(int i=1;i<(1<<20);i++)pw[i]=3ll*pw[i-1]%mod;
    fwt(a,1<<20);
    for(int i=0;i<(1<<20);i++){
        int cnt=(a[i]+n)>>1;
        if(n-cnt&1)ans=(ans-pw[cnt]+mod)%mod;
        else ans=(ans+pw[cnt])%mod;
    }
    ans=1ll*ans*qpow(1<<20,mod-2)%mod-1+mod;
    printf("%d\n",ans%mod);
    return 0;
}

标签:黎明前,cnt,int,巧克力,异或,ans,dp,mod
From: https://www.cnblogs.com/gtm1514/p/17353722.html

相关文章

  • 「解题报告」UOJ310 黎明前的巧克力
    我还是太不懂FWT了!首先发现,两个人的集合异或和相等,那么这两个人的集合的并的异或和等于\(0\),而相对应地,每一个大小为\(k\)的异或和为\(0\)的集合都有\(2^k\)种方案。那么我们实际上就是要找所有异或和等于\(0\)的方案数。考虑集合幂级数刻画,那么我们要求的就是\(n\)......
  • 分巧克力
    分巧克力蓝桥杯分巧克力思路:发现可以分的块数是由(Hi/a)*(Wi/a)得来,a正方形边长(原理:"/"自动向下取整)观察数据量,10^5时间2s可以用二分来枚举正方形可能的边数写一个check函数,对长度合理的边进行处理publicclassN99{ staticintN=100010;//多......
  • 分巧克力 | 二分
      P8647[蓝桥杯2017省AB]分巧克力-洛谷|计算机科学教育新生态(luogu.com.cn)一图说清下述两种代码孰对孰错的原因:  错误代码:#include<iostream>#include<algorithm>#include<cmath>usingnamespacestd;#defineios_base\ios::sync_with_stdio(f......
  • 分巧克力(二分法)
    题目描述儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。小明一共有N块巧克力,其中第i块是Hi×Wi的方格组成的长方形。为了公平起见,小明需要从这N块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:形状是正方形,边长是整数;......
  • 吃巧克力,容器vector、map,容器适配器 priority_queue,算法sort排序
     #include<algorithm>#include<queue>#include<map>#include<vector>#include<iostream>usingnamespacestd;structchocolate{longlonga;//价......
  • 蓝桥杯2021国赛:巧克力 【贪心】
    题目描述小蓝很喜欢吃巧克力,他每天都要吃一块巧克力。一天小蓝到超市想买一些巧克力。超市的货架上有很多种巧克力,每种巧克力有自己的价格、数量和剩余的保质期天数,小蓝......
  • 计算不同年龄男性需要维持体重所需要吃的巧克力数
    #include<stdio.h>intmain(){ floatm,h,a,BMR,n; printf("请输入你的体重m(kg):"); scanf_s("%f",&m); printf("请输入你的身高h(cm):"); scanf_s("%f",&h); ......
  • 1227. 分巧克力
    https://www.acwing.com/problem/content/1229/#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>usingnamespacestd;intn,k;constin......