博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ3054] Rainbow的信号(考虑位运算 + DP?)
阅读量:5345 次
发布时间:2019-06-15

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

 

BZOJ没数据范围。。。

其实数据范围是这样的。。

前20%可以直接n^3暴力枚举每个区间

前40%可以考虑每一位,因为所有数每一位都是独立的,而和的期望=期望的和,那么可以枚举每一位,再枚举区间,最大 31*n*n

想到枚举每一位也就离正解不远了,可以dp,

对于xor有贡献的是区间xor值为1的区间,那么f[i]表示以i结尾的区间异或值为1的个数,那么xor就很好解决了

对于or,我们只需要找出所有的全为0的区间,拿总区间个数减去就好,

对于and,我们只需要找出所有全为1的区间即可

 

#include 
#include
#define N 100005#define LL long long#define max(x, y) ((x) > (y) ? (x) : (y))int p1, p0, mx;int a[N], f[N];LL n, num0, num1, cnt;bool b[N];double ans1, ans2, ans3;//f[i]以i结尾的 xor值为1的数量int main(){ int i, j, k; scanf("%lld", &n); for(i = 1; i <= n; i++) { scanf("%d", &a[i]); mx = max(mx, a[i]); } for(k = 0; mx; mx >>= 1, k++); for(i = 0; i < k; i++) { p0 = p1 = -1; num0 = num1 = cnt = 0; for(j = 1; j <= n; j++) { if(a[j] & (1 << i)) f[j] = j - f[j - 1]; else f[j] = f[j - 1]; cnt += f[j]; b[j] = (a[j] & (1 << i)); } for(j = 1; j <= n; j++) { if(!b[j] && p0 == -1) p0 = j; if(b[j] && p0 ^ -1) num0 += (LL)(j - p0) * (j - p0), p0 = -1; if(b[j] && p1 == -1) p1 = j; if(!b[j] && p1 ^ -1) num1 += (LL)(j - p1) * (j - p1), p1 = -1; } if(p0 ^ -1) num0 += (LL)(j - p0) * (j - p0); if(p1 ^ -1) num1 += (LL)(j - p1) * (j - p1); cnt *= 2; for(j = 1; j <= n; j++) if(a[j] & (1 << i)) cnt--; ans1 += 1.0 * (1 << i) * cnt / n / n; ans2 += 1.0 * (1 << i) * num1 / n / n; ans3 += 1.0 * (1 << i) * (n * n - num0) / n / n; } printf("%.3lf %.3lf %.3lf\n", ans1, ans2, ans3); return 0;}

  

转载于:https://www.cnblogs.com/zhenghaotian/p/7604817.html

你可能感兴趣的文章
高性能JavaScript-JS脚本加载与执行对性能的影响
查看>>
关于标签之间因为换行等问题造成的空白间距问题处理
查看>>
hdu 2767(tarjan)
查看>>
sklearn之分类模型混淆矩阵和分类报告
查看>>
MySQL各存储引擎
查看>>
项目--简单导出CSV文件
查看>>
Oracle session相关数据字典(一)
查看>>
织梦文章内容提取第一张或者多张图片输出
查看>>
C#用正则表达式 获取网页源代码标签的属性或值
查看>>
BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡(贪心)
查看>>
WCF(一) 简单的认知
查看>>
[MFC][DShow]简单例子
查看>>
降序排列
查看>>
十一、类型转换
查看>>
面试内容,值得一看
查看>>
UILabel
查看>>
【热门技术】三种SEO方式
查看>>
[Hades_技术]哈迪斯初级技术应用
查看>>
SQLiteOpenHelper
查看>>
Luogu P1141 01迷宫【搜索/dfs】By cellur925
查看>>