博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
51Nod 1684 子集价值 (平方和去括号技巧)
阅读量:5312 次
发布时间:2019-06-14

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

 

题意:

新建一个位运算,求所有子集通过这个位运算后的答案的平方和是多少。

 

先想弱化版:

新建一个位运算,求所有子集通过这个位运算后的答案的和是多少。

枚举每一个二进制位,看有多少个子集能够使这一位为1

dp[i]表示前i个数中,能使枚举的这一位为1的方案数

根据第i个数选或者是不选转移

ans= Σ  2^j * 第j位的dp[n] 

 

这里是平方和

设一个子集位运算后的结果为x,它对答案的贡献为x^2

把x按二进制拆为p位,即(x0+x1+x2+x_p-1)

其中xi表示2^i

那它对答案的贡献为 (x0+x1+x2+x_p-1)^ 2

去括号就是  x0*x0+x0*x1+……+x0*x_p-1+……+ x_p-1 * x0+x_p-1 * x1+…… x_p-1 * x_p-1

即 Σ Σ xi*xj    i,j ∈[0,p)

 每一项至于两位有关

所以枚举任意两位a,b

dp[i][0/1][0/1]表示前i个数,第a位为0/1,第b位为0/1的方案数

ans= Σ Σ 2^(i+j) * 枚举的两位为i和j时的dp[n][1][1]

 

即dp求的是表达式中每一项的系数

 

#include
#include
#include
using namespace std;#define N 50001const int mod=1e9+7;int n,p; int to[2][2];int b[N];int dp[N][2][2];void read(int &x){ x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }} int get(int p,int q){ memset(dp,0,sizeof(dp)); bool pp,qq; for(int i=1;i<=n;++i) { pp=b[i]>>p&1; qq=b[i]>>q&1; dp[i][pp][qq]++; dp[i][pp][qq]-=dp[i][pp][qq]>=mod ? mod : 0; for(int j=0;j<2;++j) for(int k=0;k<2;++k) { dp[i][j][k]+=dp[i-1][j][k]; dp[i][j][k]-=dp[i][j][k]>=mod ? mod : 0; dp[i][to[j][pp]][to[k][qq]]+=dp[i-1][j][k]; dp[i][to[j][pp]][to[k][qq]]-=dp[i][to[j][pp]][to[k][qq]]>=mod ? mod : 0; } } return dp[n][1][1];}int main(){ read(n); read(p); for(int i=0;i<2;++i) for(int j=0;j<2;++j) read(to[i][j]); for(int i=1;i<=n;++i) read(b[i]); int ans=0; for(int i=0;i
=mod ? mod : 0; } cout<

 

 
基准时间限制:5 秒 空间限制:131072 KB 分值: 80 
 收藏
 关注

 

lyk最近在研究位运算。

它发现除了xor,or,and外还有很多运算。

它新定义了一种运算符“#”。

具体地,可以由4个参数来表示。

 ai,j

其中i,j与a的值均∈[0,1]。

当然问题可以扩展为>1的情况,具体地,可以将两个数分解为p位,然后对于每一位执行上述的位运算,再将这个二进制串转化为十进制就可以了。

例如当 a0,0=a1,1=0,a0,1=a1,0=1,3#4在p=3时等于7,2#3在p=4时等于1(实际上就是异或运算)。

现在lyk想知道的是,已知一个数列b。

它任意选取一个序列c,满足 c1<c2<...<ck1c1ckn ,这个序列的价值为 bc1 # bc2 #...# bck 的平方。

这里我们假设k是正整数,因此满足条件的c的序列一定是 2n1 。lyk想知道所有满足条件的序列的价值总和是多少。

例如样例中,7个子集的价值分别为1,1,4,4,9,9,0。总和为28。

由于答案可能很大,只需对1,000,000,007取模即可。

 

Input
第一行两个整数n(1<=n<=50000),p(1<=p<=30)。第二行4个数表示a0,0,a0,1,a1,0,a1,1。(这4个数都∈{0,1})第三行n个数bi(0<=bi<2^p)。
Output
一行表示答案。
Input示例
3 300 1 1 01 2 3
Output示例
28

 

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/8454505.html

你可能感兴趣的文章
【转】ACM之Java新手速成
查看>>
日志分析工具 Log Parser
查看>>
18 HTML标签以及属性全
查看>>
vim 复制操作
查看>>
【codeforces 789C】Functions again
查看>>
【t067】补充装备
查看>>
【t060】可怜的波特
查看>>
解决Storm 和yarn 8080 端口冲突
查看>>
tensorflow 前向传播 2019.07.19
查看>>
MVP设计模式
查看>>
安装完CentOS 7 Minimal之后,从头打造桌面工作环境
查看>>
hadoop fs、hadoop dfs与hdfs dfs命令的区别
查看>>
学习转载:电源纹波测量的正确方法
查看>>
ajax删除,
查看>>
ZOJ 3469 Food Delivery(区间DP好题)
查看>>
3.20样式
查看>>
面向对象下
查看>>
Java关键字final、static使用总结 (final static在容器中不可以改变容器但可以改变存放)...
查看>>
Cobalt Strike深入使用
查看>>
HDU 2993 MAX Average Problem
查看>>