Codeforces 题目传送门 & 洛谷题目传送门

首先很容易注意到一件事,那就是对于所有 \(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 次方和)的更多相关文章

  1. 【CF772D】Varying Kibibits FWT

    [CF772D]Varying Kibibits 题意:定义函数f(a,b,c...)表示将a,b,c..的10进制下的每一位拆开,分别取最小值组成的数.如f(123,321)=121,f(530,  ...

  2. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  3. Educational Codeforces Round 61 C 枚举 + 差分前缀和

    https://codeforces.com/contest/1132/problem/C 枚举 + 差分前缀和 题意 有一段[1,n]的线段,有q个区间,选择其中q-2个区间,使得覆盖线段上的点最多 ...

  4. Codeforces Gym 100015G Guessing Game 差分约束

    Guessing Game 题目连接: http://codeforces.com/gym/100015/attachments Description Jaehyun has two lists o ...

  5. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  6. [Codeforces]817F. MEX Queries 离散化+线段树维护

    [Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...

  7. CodeForces 408E Curious Array(组合数学+差分)

    You've got an array consisting of n integers: a[1], a[2], ..., a[n]. Moreover, there are m queries, ...

  8. Codeforces Global Round 2 D 差分 + 前缀和 + 二分

    https://codeforces.com/contest/1119/problem/D 题意 有n个数组,每个数组大小为\(10^{18}+1\)且为等差数列,给出n个数组的\(s[i]\),q次 ...

  9. CodeForces 675C Money Transfers(贪心+奥义维护)

    题意:n个银行. 其中存款有+有-. 总和为0. n个银行两两相邻((1,n),(1,2)...(n-1,n)); 问最少移动几次(只能相邻移动)能把所有数变为0. 分析:思路很简单,起始答案算它为n ...

随机推荐

  1. 初学Python-day8 案例2

    中奖率 1 import random 2 num = 123456 3 i = 1 4 while True: 5 win = random.randrange(100000, 999999) 6 ...

  2. 【UE4 C++ 基础知识】<7> 容器——TSet

    概述 TSet是一种快速容器类,(通常)用于在排序不重要的情况下存储唯一元素. TSet 类似于 TMap 和 TMultiMap,但有一个重要区别:TSet 是通过对元素求值的可覆盖函数,使用数据值 ...

  3. Java:基本概念小记

    Java:基本概念 一些基本 Java 概念,做一个小小小小的记录 面向对象&面向过程 面向对象思想就是在计算机程序设计过程中,参照现实中事物,将事物的属性特征.行为特征抽象出来,描述成计算机 ...

  4. 微信小程序实现上拉和下拉加载更多

    在上一篇文章中,我们知道了使用 scroll-view 可以实现上拉加载更多,但是由于 scroll-view 的限制,它无法实现下拉加载更多,这篇文章我们使用 view 组件来实现 上拉和下拉加载更 ...

  5. (四)、Docker 镜像

    1.Docker镜像是什么? 镜像是一种轻量级.可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码.运行时.库.环境变量和配置文件. 2.Do ...

  6. CSP踩被记

    本来想起个清新脱俗的标题,但碍于语文功底不行,于是光明正大嫖了LiBoyi的高端创意,把这篇博客命名为踩被记. Day -6 用假暴力把真正解拍没了,伤心.Rp有点低 Day -4 信息学考,\(py ...

  7. str数组

  8. 《基于SIR的路边违停行为传播模型研究》

    My Focus: 路边违停 行为的传播模型; 学习基于SIR XXX模型的可行性分析.建立和结论分析 Author: 左忠义,王英英,包蕴 Mind Map:

  9. Spring Security 的注册登录流程

    Spring Security 的注册登录流程 数据库字段设计 主要数据库字段要有: 用户的 ID 用户名称 联系电话 登录密码(非明文) UserDTO对象 需要一个数据传输对象来将所有注册信息发送 ...

  10. objcopy使用

    objcopy - copy and translate object files:用于二进制文件的拷贝和翻译(转化) objcopy的man文件如下所示: objcopy [-F bfdname|- ...