博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【CF772D】Varying Kibibits FWT
阅读量:5459 次
发布时间:2019-06-15

本文共 1058 字,大约阅读时间需要 3 分钟。

【CF772D】Varying Kibibits

题意:定义函数f(a,b,c...)表示将a,b,c..的10进制下的每一位拆开,分别取最小值组成的数。如f(123,321)=121,f(530, 932, 81)=30。给你一个数集$T={a_1,a_2...a_n}$,定义函数G(x)

求$G(1)\oplus G(2)\oplus ...G(999999)$。

$1\le n \le 1000000,0\le a_i \le 999999$

题解:发现f函数就是10进制下的按位与,所以我们先对原序列进行fwt。具体地说,因为上面那个式子里有平方,所以我们要维护3个东西,a[i]表示T中i的个数,b[i]=a[i]*i,c[i]=a[i]*i*i。将这三个东西都进行fwt。

怎么统计呢?我们要求的就是一个集合的所有子集的元素的完全平方和。设当前的集合为U,我们考虑其中一个元素y的贡献,如果$S\subseteq U-y$,那么y会在$S+y$和$U-S$里分别被统计,也就是说其贡献是$y\times 2^{|U|-2}(b[U]+y)$。所以总的贡献就是$2^{|U|-2}(b[U]^2+c[U])$。特判:当a[U]=1时,贡献就是c[U];当a[U]=0时,贡献=0。

再逆fwt回去就好了。

 

#include 
#include
#include
using namespace std;const int maxn=1000010;typedef long long ll;const ll P=1000000007;int n,len;ll ans;ll a[maxn],b[maxn],c[maxn],f[maxn],bt[maxn];inline int rd(){ int ret=0,f=1; char gc=getchar(); while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();} while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar(); return ret*f;}inline void fwt(){ int h,i; for(h=1;h

 

转载于:https://www.cnblogs.com/CQzhangyu/p/8445231.html

你可能感兴趣的文章
隐藏浏览器原生的滚动条
查看>>
[spring mvc]<mvc: annotation-driven />的作用
查看>>
jsplumb
查看>>
20135304刘世鹏——信息安全系统设计基础第十二周总结
查看>>
C++ 连接mysql数据库
查看>>
基于C#开发的简易贪吃蛇
查看>>
Vue 源码解析:深入响应式原理(上)
查看>>
poj2318 TOYS
查看>>
012木桶绕圆滚动
查看>>
having的用法以及与where区别介绍
查看>>
责任链模式
查看>>
Python并行编程(五):线程同步之信号量
查看>>
SQLServer 日期函数大全
查看>>
Maven-pom-configuration
查看>>
火狐无法访问本机IIS部署的网站,弹出:此地址使用了一个通常用于网络浏览以外目的的端口.出于安全原因,Firefox 取消了该请求 的解决办法...
查看>>
前端兼容性问题解决方案(二)
查看>>
JVM调优(二)经验参数设置
查看>>
博弈学习笔记
查看>>
LinQ Lambda表达式用作泛型活动
查看>>
python 基础学习1
查看>>