Codeforces 772D - Varying Kibibits(高维差分+二项式定理维护 k 次方和)
首先很容易注意到一件事,那就是对于所有 \(f(S)\) 可能成为 \(x\) 的集合 \(S\),必定有 \(\forall y\in S\),\(x\) 的每一位都 \(\le y\) 的对应位,于是我们考虑设 \(h(x)\) 表示所有满足 \(x\) 的对应位都小于 \(f(S)\) 的对应位的 \(S\) 的贡献之和,显然我们求出 \(h(x)\) 之后,可以把 \(0\sim 999999\) 中的数都看作一个拥有六个维度,每个维度中的数都 \(\in[0,9]\) 的元素,然后仿照二进制下的高维差分跑一遍高维差分即可。
接下来考虑怎样求出 \(h(x)\),下记 \([x\subseteq y]\) 表示 \(x\) 是否每一位都 \(\le y\) 的对应位,那显然根据之前的定义有 \(h(x)=\sum\limits_{S\subseteq T}[\forall y\in S,x\subseteq y](\sum\limits_{y\in S}y)^2\),这里面带个平方,可能不是特别显然,我们考虑一个简单些的问题,那就是假设每个集合 \(S\) 的贡献都是 \(1\) 而不是 \((\sum\limits_{y\in S}y)^2\),那我们只需求出 \(c(x)=\sum\limits_{y\in T}[x\subseteq y]\),那么显然就有 \(h(x)=2^{c(x)}\)。回到原题,注意到我们高维前缀和的实质是合并两个集合 \(S,T\) 的贡献,也就是倘若我们已经知道了 \(S\) 的贡献和 \(T\) 的贡献,怎样支持快速求出 \(S\cup T\) 的贡献。我们如果记 \(st(x)=\{y|y\in T,x\subseteq y\}\),那么 \(h(x)=\sum\limits_{S\subset st(x)}(\sum\limits_{y\in S}y)^2\)。并且此题还带个平方,做过 P6144 [USACO20FEB]Help Yourself P 的同学应该都知道,碰到这类高次方求和的问题,我们都可用二项式定理将其拆成若干个低次方的和,然后将它们一一合并即可。具体来说,根据二项式定理初一课内有 \((x+y)^2=x^2+2xy+y^2\),故我们对于每个集合 \(S\) 维护零次方和、一次方和和二次方和,即 \(S_0=\sum\limits_{S'\subseteq S}1,S_1=\sum\limits_{S'\subseteq S}\sum\limits_{x\in S'}x,S_2=\sum\limits_{S'\subseteq S}(\sum\limits_{x\in S'}x)^2\),那么当合并两个集合 \(S,T\) 时,就有:
- \((S\cup T)_0=\sum\limits_{U\subseteq(S\cup T)}1=\sum\limits_{U\subseteq S,V\subseteq T}1=\sum\limits_{U\subseteq S}\sum\limits_{V\subseteq T}1=S_0T_0\)
- \[\begin{aligned}(S\cup T)_1&=\sum\limits_{U\subseteq(S\cup T)}\sum\limits_{x\in U}x=\sum\limits_{U\subseteq S,V\subseteq T}(\sum\limits_{x\in U}x+\sum\limits_{x\in V}x)\\&=\sum\limits_{U\subseteq S}\sum\limits_{V\subseteq T}(\sum\limits_{x\in U}x+\sum\limits_{x\in V}x)\\&=\sum\limits_{U\subseteq S}\sum\limits_{x\in U}x·\sum\limits_{V\subseteq T}1+\sum\limits_{V\subseteq T}\sum\limits_{x\in V}x·\sum\limits_{U\subseteq S}1\\&=S_1T_0+S_0T_0\end{aligned}
\] - \[\begin{aligned}(S\cup T)_2&=\sum\limits_{U\subseteq(S\cup T)}(\sum\limits_{x\in U}x)^2=\sum\limits_{U\subseteq S,V\subseteq T}(\sum\limits_{x\in U}x+\sum\limits_{x\in V}x)^2\\&=\sum\limits_{U\subseteq S}\sum\limits_{V\subseteq T}((\sum\limits_{x\in U}x)^2+(\sum\limits_{x\in V}x)^2+2\sum\limits_{x\in U}x\sum\limits_{x\in V}x)\\&=\sum\limits_{U\subseteq S}(\sum\limits_{x\in U}x)^2·\sum\limits_{V\subseteq T}1+\sum\limits_{V\subseteq T}(\sum\limits_{x\in V}x)^2·\sum\limits_{U\subseteq S}1+2\sum\limits_{U\subseteq S}\sum\limits_{x\in U}x·\sum\limits_{V\subseteq T}\sum\limits_{x\in V}x\\&=S_2T_0+S_0T_2+2S_1T_1\end{aligned}
\]
高维前缀和维护下即可,最好开个结构体,时间复杂度 \(6\times 999999\)。
老缝合怪了
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=1e6;
const int MOD=1e9+7;
int n,pw[MAXN+5],ret[MAXN+5];
struct data{
int sum0,sum1,sum2;
data(){sum0=sum1=sum2=0;}
data(int x){sum0=1;sum1=x;sum2=1ll*x*x%MOD;}
data(int _sum0,int _sum1,int _sum2):sum0(_sum0),sum1(_sum1),sum2(_sum2){}
data operator +(const data &rhs){
return data(
sum0+rhs.sum0,
(1ll*sum1*pw[rhs.sum0]+1ll*pw[sum0]*rhs.sum1)%MOD,
(1ll*sum2*pw[rhs.sum0]%MOD+2ll*sum1*rhs.sum1+1ll*pw[sum0]*rhs.sum2)%MOD);
}
} f[MAXN+5];
int main(){
scanf("%d",&n);pw[0]=1;
for(int i=1;i<=n;i++) pw[i]=2ll*pw[i-1]%MOD;
for(int i=1,x;i<=n;i++) scanf("%d",&x),f[x]=f[x]+data(x);
int cur=1;
for(int i=0;i<=5;i++){
for(int j=MAXN-1;~j;j--){
if((j/cur)%10!=9) f[j]=f[j]+f[j+cur];
}
cur=cur*10;
}
for(int i=0;i<MAXN;i++) ret[i]=f[i].sum2;
cur=1;
for(int i=0;i<=5;i++){
for(int j=0;j<MAXN;j++){
if((j/cur)%10!=9) ret[j]=(ret[j]-ret[j+cur]+MOD)%MOD;
}
cur=cur*10;
} ll ans=0;
for(int j=0;j<MAXN;j++) ans^=1ll*j*ret[j];
printf("%lld\n",ans);
return 0;
}
Codeforces 772D - Varying Kibibits(高维差分+二项式定理维护 k 次方和)的更多相关文章
- 【CF772D】Varying Kibibits FWT
[CF772D]Varying Kibibits 题意:定义函数f(a,b,c...)表示将a,b,c..的10进制下的每一位拆开,分别取最小值组成的数.如f(123,321)=121,f(530, ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- Educational Codeforces Round 61 C 枚举 + 差分前缀和
https://codeforces.com/contest/1132/problem/C 枚举 + 差分前缀和 题意 有一段[1,n]的线段,有q个区间,选择其中q-2个区间,使得覆盖线段上的点最多 ...
- Codeforces Gym 100015G Guessing Game 差分约束
Guessing Game 题目连接: http://codeforces.com/gym/100015/attachments Description Jaehyun has two lists o ...
- Codeforces GYM 100114 D. Selection 线段树维护DP
D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...
- [Codeforces]817F. MEX Queries 离散化+线段树维护
[Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...
- CodeForces 408E Curious Array(组合数学+差分)
You've got an array consisting of n integers: a[1], a[2], ..., a[n]. Moreover, there are m queries, ...
- Codeforces Global Round 2 D 差分 + 前缀和 + 二分
https://codeforces.com/contest/1119/problem/D 题意 有n个数组,每个数组大小为\(10^{18}+1\)且为等差数列,给出n个数组的\(s[i]\),q次 ...
- CodeForces 675C Money Transfers(贪心+奥义维护)
题意:n个银行. 其中存款有+有-. 总和为0. n个银行两两相邻((1,n),(1,2)...(n-1,n)); 问最少移动几次(只能相邻移动)能把所有数变为0. 分析:思路很简单,起始答案算它为n ...
随机推荐
- python jinja2初见
吸取了长城杯的教训,学习python-web迫在眉睫. 正常难度的python_template_injection,由于现在没学面向对象,理解原理比较困难,所以先使用简单版复现:并附上正常版的常用p ...
- [对对子队]会议记录4.18(Scrum Meeting9)
今天已完成的工作 何瑞 工作内容:修复了一些关卡1的bug 相关issue:搭建关卡1 相关签入:4.18签入1 4.18签入2 梁河览 工作内容:实现了音量控制,添加了BGM 相 ...
- OO第三单元JML总结
目录 目录一.JML语言的理论基础二.应用工具链三.部署SMT Solver四.部署JMLUnitNG/JMLUnit五.三次作业分析第一次作业第二次作业第三次作业六.总结与心得体会 一.JML语言的 ...
- Python Linux Ubuntu apt安装PyCharm
PyCharm一个是Python集成开发环境,它既提供收费的专业版,也提供免费的社区版本.PyCharm带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试.语法高亮.Proj ...
- 攻防世界 Misc 新手练习区 gif Writeup
攻防世界 Misc 新手练习区 gif Writeup 题目介绍 题目考点 仔细联想 字符转换 Writeup 下载附件并打开 104张黑白图 发现是一堆黑色和白色的图片,按某种规律排列,猜想flag ...
- LoadRunner12回放与录制
系统版本 本人的操作系统是win10 版本是loadrunner12. 开启loadrunner自带的机票预订服务器 找到loadrunner自带的机票预订测试服务器下图中点击启动 如下图所示代表启动 ...
- Spark中的两种模式
两种模式 client-了解 cluster模式-开发使用 操作 1.需要Yarn集群 2.历史服务器 3.提交任务的的客户端工具-spark-submit命令 4.待提交的spark任务/程序的字节 ...
- 深入理解Spring IOC容器
本文将从纯xml模式.xml和注解结合.纯注解的方式讲解Spring IOC容器的配置和相关应用. 纯XML模式 实例化Bean的三种方式: 使用无参构造函数 默认情况下,会使用反射调用无参构造函数来 ...
- windows 上搭建 sftp 服务器 -freesshd全过程( 在linux上部署逐浪CMS的必读教程)
文章标题: windows 上搭建 sftp 服务器 - freesshd全过程 关键字 : freesshd 文章分类: 教程 创建时间: 2020年3月23日 缘由 动手 第一步:添加用户 第二步 ...
- Python基础(dict与set)
#和list比较,dict有以下几个特点: #查找和插入的速度极快,不会随着key的增加而变慢: #需要占用大量的内存,内存浪费多. #dict1 = {'傻狗1':100,'傻狗2':200,'傻狗 ...