二进制拆位计算贡献

题目描述

树状数组是一种常用的数据结构,下面是树状数组用于给区间 [1,x] 内的数加 t 的代码:

 void add(int x,int t){
for (int i=x;i;i-=(i&(-i))){
cnt[i]+=t;
}
}

当你要给 [l,r] 区间加 x 时,肯定是先给 [1,l−1] 加 −x,然后给 [1,r] 加 x

令 f(l,r) 为:在 cnt 数组一开始为 0 的情况下给区间[l,r]区间加1后,cnt 数组有多少位置不为0。

现在给定 n,求  \sum_{l=1}^{n} \sum_{r=1}^{n} f(l,r),对1e9+7取模

输入格式

第一行 T

T 行, 一个 n

输出格式

T 行答案

数据范围

1≤n≤10^18,1≤T≤10^4


题目分析

这题主流做法是数位dp。不过从hdu5921Binary Indexed Tree学习到一种拆位算贡献的方法

(但是请注意!上面引用的这篇博客关于f(i),g(i)的分析有写错的地方!)

本题树状数组求的是后缀和;而∑f(l,r)求的是l-1和r这两个数在依次减去lowbit的过程中不同的数的个数:那么只有当l-1和r变成lcp(l-1,r)时,接下去的数才会相同。

记g(i)为i二进制中1的个数,所求即

(公式崩了只能用图片)

经过上面分析之后,问题相当于转变为求∑g(i)和Σg(lcp(l-1,r))。由于数据范围是10^18级别,显然我们需要log算法。

将n二进制拆位,考虑从右往左第$i$位的贡献。记[i+1...lens]在十进制下为nxt[i+1],[1...i-1]在十进制下为pre[i-1]。

1.计算gi第一步:左边的数不改变

那么为了不大于原数,右边的数应取0...pre[i-1]。

当ai==1时,有pre[i-1]+1的贡献

2.计算gi第二步:左边的数可改变

与上一种情况相对应,左边的数应取0...nxt[i+1]-1.那么此时右边的数可以任意取值,有2^i种取值。

所以这种情况下,无论ai取值如何,都有nxt[i+1]*2^i的贡献。

至于还要处理两两lcp的部分,则与之类似。由于是数对之间的负贡献,算的时候再多乘上去就好了。

 #include<bits/stdc++.h>
typedef long long ll;
const ll MO = ; int T,bin[],lens;
ll n,ans,power[],pre[],nxt[]; ll read()
{
char ch = getchar();
ll num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
int main()
{
T = read(), power[] = ;
for (int i=; i<=; i++) power[i] = (power[i-]<<)%MO;
while (T--)
{
n = read(), ans = lens = ;
for (ll x=n; x; x>>=) bin[++lens] = x&;
pre[] = nxt[lens+] = ;
for (int i=; i<=lens; i++) pre[i] = (pre[i-]+power[i-]*bin[i])%MO;
for (int i=lens; i>=; i--) nxt[i] = ((nxt[i+]<<)+bin[i])%MO;
for (int i=; i<=lens; i++)
{
if (bin[i]) pre[i-]++, ans = (ans+pre[i-])%MO;
ans = (ans+nxt[i+]*power[i-]%MO)%MO;
}
ans = (n+1ll)%MO*ans%MO;
for (int i=; i<=lens; i++)
{
if (bin[i]) ans = (ans+MO-pre[i-]*pre[i-]%MO)%MO;
ans = (ans-nxt[i+]*power[i-]%MO*power[i-]%MO+MO)%MO;
}
printf("%lld\n",ans);
}
return ;
}

END

【计数】hdu5921Binary Indexed Tree的更多相关文章

  1. Hdu5921 Binary Indexed Tree

    Hdu5921 Binary Indexed Tree 思路 计数问题,题目重点在于二进制下1的次数的统计,很多题解用了数位DP来辅助计算,定义g(i)表示i的二进制中1的个数, $ans = \su ...

  2. Binary Indexed Tree

    我借鉴了这个视频中的讲解的填坑法,我认为非常易于理解.有FQ能力和基本英语听力能力请直接去看视频,并不需要继续阅读. naive 算法 考虑一个这样的场景: 给定一个int数组, 我们想知道它的连续子 ...

  3. Leetcode: Range Sum Query 2D - Mutable && Summary: Binary Indexed Tree

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  4. SRM 627 D1L2GraphInversionsDFS查找指定长度的所有路径 Binary indexed tree (BIT)

    题目:http://community.topcoder.com/stat?c=problem_statement&pm=13275&rd=16008 由于图中边数不多,选择DFS遍历 ...

  5. 树状数组(Binary Indexed Tree,BIT)

    树状数组(Binary Indexed Tree) 前面几篇文章我们分享的都是关于区间求和问题的几种解决方案,同时也介绍了线段树这样的数据结构,我们从中可以体会到合理解决方案带来的便利,对于大部分区间 ...

  6. Binary Indexed Tree (Fenwick Tree)

    Binary Indexed Tree 主要是为了存储数组前缀或或后缀和,以便计算任意一段的和.其优势在于可以常数时间处理更新(如果不需要更新直接用一个数组存储所有前缀/后缀和即可).空间复杂度O(n ...

  7. Binary Indexed Tree 总结

    特点 1. 针对 数组连续子序列累加和 问题(需要进行频繁的 update.sum 操作): 2. 并非是树型结构,只是逻辑上层次分明: 3. 可以通过 填坑法 来理解: 4. 中心思想:每一个整数都 ...

  8. 树状数组(Binary Indexed Tree)

    树状数组(Binary Indexed Tree,BIT) 是能够完成下述操作的数据结构. 给一个初始值全为 0 的数列 a1, a2, ..., an (1)给定 i,计算 a1+a2+...+ai ...

  9. LeetCode10 Indexed tree

    Binary Indexed Tree(Fenwick tree): 是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修 ...

随机推荐

  1. IP服务-8-WCCP

    WCCP(网页缓存通信协议) 内容引擎负责将频繁访问的数据收集到本地,通常是HTTP流量,当主机访问相同页面时,可以直接通过内容引擎为主机提供相应内容,而无需通过WAN进行访问.WCCP与网页代理并不 ...

  2. Python-13-pass,del和exec

    1.pass就是什么都不做 >>> pass >>>   2. 对于你不再使用的对象, Python通常会将其删除(因为没有任何变量或数据结构成员指向它) . &g ...

  3. Spark Mllib里的分布式矩阵(行矩阵、带有行索引的行矩阵、坐标矩阵和块矩阵概念、构成)(图文详解)

    不多说,直接上干货! Distributed  matrix : 分布式矩阵 一般能采用分布式矩阵,说明这数据存储下来,量还是有一定的.在Spark Mllib里,提供了四种分布式矩阵存储形式,均由支 ...

  4. 洪水(flood)

    洪水(flood) 题目背景 Awson是某国际学校信竞组的一只菜鸡.今年,该市发生了千年难遇的洪水.被监禁在学校的Awson不甘怠堕,想将自己投入到公益服务事业中去.这天,他偷了H老师的小电驴,偷偷 ...

  5. 密码强度的正则表达式(JavaScript)总结

    简言 本文给出了两个密码强度的正则表达式方案,一个简单,一个更复杂和安全.并分别给出了两个方案的解析和测试程序.一般大家可以根据自己的项目的实际需要,自行定义自己的密码正则约定. 前言 用户注册时,都 ...

  6. Myeclipse连接数据库删除数据库(JDBC)

    package com.test.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Pr ...

  7. javascript结合nodejs实现多文件上传

    前端文件上传功能比较依赖后端,所以第一步用nodejs实现一个供文件上传的功能接口. 因为本人对nodejs也是一知半解,所以刚开始的想法是像原始的ajax交互那样,获取上传文件的内容,然后再通过no ...

  8. Echarts获取数据绘制图表

    这次是利用mui框架实现一个手机移动端的项目.基本的框架已经实现,主要来获取数据实现一个图表的展示. 首先引入插件:echarts.js <script src="../resourc ...

  9. JFinal教程:JFinal极速开发企业实战百集JFinal视频教程发布

    课程名称:JFinal极速开发企业实战 课程长度:100课时 课程作者:小木(909854136) 课程地址:http://edu.csdn.net/course/detail/1968 官网网址:h ...

  10. 多段图动态规划dp

    多段图问题是DP的基础题目.大体的意思是有一个赋权有向图,其顶点集被分为几个子集.求经过每个子集从源点到终点的最短路径 import java.util.ArrayList; import java. ...