【计数】hdu5921Binary Indexed Tree
二进制拆位计算贡献
题目描述
树状数组是一种常用的数据结构,下面是树状数组用于给区间 [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的更多相关文章
- Hdu5921 Binary Indexed Tree
Hdu5921 Binary Indexed Tree 思路 计数问题,题目重点在于二进制下1的次数的统计,很多题解用了数位DP来辅助计算,定义g(i)表示i的二进制中1的个数, $ans = \su ...
- Binary Indexed Tree
我借鉴了这个视频中的讲解的填坑法,我认为非常易于理解.有FQ能力和基本英语听力能力请直接去看视频,并不需要继续阅读. naive 算法 考虑一个这样的场景: 给定一个int数组, 我们想知道它的连续子 ...
- 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 ...
- SRM 627 D1L2GraphInversionsDFS查找指定长度的所有路径 Binary indexed tree (BIT)
题目:http://community.topcoder.com/stat?c=problem_statement&pm=13275&rd=16008 由于图中边数不多,选择DFS遍历 ...
- 树状数组(Binary Indexed Tree,BIT)
树状数组(Binary Indexed Tree) 前面几篇文章我们分享的都是关于区间求和问题的几种解决方案,同时也介绍了线段树这样的数据结构,我们从中可以体会到合理解决方案带来的便利,对于大部分区间 ...
- Binary Indexed Tree (Fenwick Tree)
Binary Indexed Tree 主要是为了存储数组前缀或或后缀和,以便计算任意一段的和.其优势在于可以常数时间处理更新(如果不需要更新直接用一个数组存储所有前缀/后缀和即可).空间复杂度O(n ...
- Binary Indexed Tree 总结
特点 1. 针对 数组连续子序列累加和 问题(需要进行频繁的 update.sum 操作): 2. 并非是树型结构,只是逻辑上层次分明: 3. 可以通过 填坑法 来理解: 4. 中心思想:每一个整数都 ...
- 树状数组(Binary Indexed Tree)
树状数组(Binary Indexed Tree,BIT) 是能够完成下述操作的数据结构. 给一个初始值全为 0 的数列 a1, a2, ..., an (1)给定 i,计算 a1+a2+...+ai ...
- LeetCode10 Indexed tree
Binary Indexed Tree(Fenwick tree): 是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修 ...
随机推荐
- iOS - 验证输入的是否是正确的身份证号码和手机号码
- (BOOL)checkIdentityCardNo:(NSString*)cardNo { if (cardNo.length != 18) { return NO; } NSArray* co ...
- PJzhang:web漏洞扫描工具sitadel
猫宁!!! 参考链接:https://www.freebuf.com/sectool/194769.html 转变博客的写作思路,力求精简快捷,不浪费自己或者他人的时间. sitadel是一款精简的w ...
- uoj207共价大爷游长沙
话说我可能还没有调出魔法森林呢...说好的lct第一题呢... 又是一个随机化的方法,毕竟又是判定性的问题 上次是判断无向图联通 这次是判断一些路径是否经过一条定边 若把路径上的边全部异或上一个路径的 ...
- NET CORE 基础
NET CORE 基础管理系统 [SF]开源的.NET CORE 基础管理系统 - 安装篇 [SF]开源的.NET CORE 基础管理系统 -系列导航 1.开发必备工具 IDE:VS2017 运行 ...
- 046 Permutations 全排列
给定一个含有不同数字的集合,返回所有可能的全排列.比如,[1,2,3] 具有如下排列:[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2 ...
- feign客户端传参数报错
新手经常遇到的错误 Caused by: java.lang.IllegalStateException: Method has too many Body parameters feign多参数问题 ...
- Activemq和Rabbitmq端口冲突
端口5672被占用了!使用cmd命令行查到被erl.exe占用了,想到这不是RabbitMQ的服务嘛 netstat -aon | findstr "5672"tasklist | ...
- Xamarin.Form的坑
首先说到xamarin.Forms的安装,简直是坑+坑+坑,为什么呢,有些坑你完全意想不到,比如说你改名字后报错,比如说上份代码能运行,在这里就不能运行,具体先将坑说说吧 坑1 文件名,动不动就报什么 ...
- JAVA基础之Date类、DateFormat类及Calendar类
个人理解: 关于Date类,进行截取或者转换时一定要注意好数据类型,long类型后面要加上L.时间的原点是1970年.用DateFormat则完成日期与文本之间的转换,特别注意的是:月是用M,时是用H ...
- DHTMLX 使用汇总
1.dhtmlxGrid 底部总出现滚动条 ------------------------------------------ 发现使用DHTMLXGRID时 GRID 底边总有 滚动条 测试 ...