CCPC长春赛区K题 hdu 5921 Binary Indexed Tree

2020(11.01)-CCPC-绵阳-(D,G,J,K,L)题解 D.Defuse the Bombs(二分答案) 思路:直接二分答案K,判断能不能在K次操作以内,把所有的数都变成 >= K就行了。最后答案等于K+1 AC代码: #include <bits/stdc++.h> #define int long long #define showcase cout<<"Case #"<<cas++<<": "; using namespace std; int a[100050]; int T,cas = 1; int 阅读详情

题目

Binary Indexed Tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 42    Accepted Submission(s): 7


Problem Description
Recently, Mr. Frog has learned binary indexed tree. Here is the code of adding t to the interval [1,x]:
    void add (int x, int t ){
        for (int i = x; i != 0; i -= i & (-i))
            a[i] += t;
    }


If Mr. Frog is required to add t to the interval [l,r], he will add(r,t), and then add(l - 1,-t).

The cost of an interval [l,r] is defined as the number of the “really changed point”. The “really changed point” is the point whose value is modified by the given code.

For example, in order to add 1 to the interval [6,6], Mr. Frog will add 1 to the interval [1,6] (a[6] and a[4] will be added by 1), and add -1 to the interval [1,5] (a[5] and a[4] will be added by -1).

As the result, a[6] will be added by 1, a[5] will be added by -1, and a[4] will be added by 0. a[6] and a[5] are “really changed point”, and the cost is 2.

Mr. Frog wants to calculate the sum of the cost of the interval [l,r]⊆  [1,n] where l and r are two integers. Help Mr. Frog solve the problem.
 

Input
The first line contains only one integer T (T≤10000), which indicates the number of test cases.

For each test case, it contains an integer n (1≤n≤1018).
 

Output
For each test case, output one line ”Case #x: y”, where x is the case number (starting from 1), y is the sum of the cost (modulo 1000000007).
 

Sample Input
3 1 2 3
 

Sample Output
Case #1: 1 Case #2: 4 Case #3: 10

大意

分析之后题意就是,给出一个n,求由[0,n]中的数组成的所有二元组(x,y)其中x<y的cost值的和,这个cost的计算方法是,把x不断地减去二进制表示下的最末尾一个1,比如(10101->10100->10000->0),把出现过的数放到集合S_x,y做相同处理形成集合S_y,cost就是两个集合中出现了1次的数的个数。

分析

用总和减去重复的,在不考虑重复的情况下,某个数的cost就是这个数二进制下1的个数,因为每个数会被用到n次,所以总共是n*(1到n的数中二进制下1的总和),这个可以用数位dp的方法,f[i][j]表示长度为i的前面已经出现了j个1的数的个数。
重复部分的计算比较麻烦,注意到对于某个二元组,他们之间会产生的重复的对数是这两个数写成二进制,并向右对齐,前面补0(比如x=10010,y=110,写成x=10010,y=00110),他们的cost是从左开始看完全重复的部分里1的个数,比如(1010010和1011010的cost是2),然后设sg[i][j]表示长度为i的并且前面完全相同部分有j个1的二元组的对数,这个数组可以直接用组合数算出来。

代码

#include<cstdio>
#include<cstring>
#define LL __int64
#define mod 1000000007
LL f[70][70],sg[70][70],mi[70],C[70][70];
int dig[70],len;
void init()
{
    int i,j,k;
    memset(f,0,sizeof(f));
    memset(sg,0,sizeof(sg));
    memset(mi,0,sizeof(mi));
    for(i=0;i<=65;i++)
    {
        C[0][i]=0;
        C[i][0]=1;
    }
    for(i=1;i<=65;i++)
        for(j=1;j<=65;j++)
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    mi[0]=1;
    for(i=1;i<=65;i++)
        mi[i]=mi[i-1]*2%mod;
    f[0][0]=1;
    f[1][1]=1;
    f[1][0]=1;
    for(i=2;i<=65;i++)
    {
        for(j=0;j<=i;j++)
        {
            if(j-1>=0)
                f[i][j]=(f[i][j]+f[i-1][j-1])%mod;
            f[i][j]=(f[i][j]+f[i-1][j])%mod;
        }
    }
    for(i=1;i<=65;i++)
    {
        sg[i][0]=(sg[i][0]+2*mi[i-1]%mod*mi[i-1]%mod)%mod;
        for(k=0;k<i-1;k++)
        {
            for(j=0;j<=k+1;j++)
            {
                sg[i][j]=(sg[i][j]+C[k+1][j]*2%mod*mi[i-k-2]%mod*mi[i-k-2]%mod)%mod;
            }
        }
    }
}
LL cal1(LL n)
{
    LL ans=0;
    int i,j;
    int cnt1=0;
    for(i=len-1;i>=0;i--)
    {
        if(dig[i]==0)
            continue;
        for(j=i;j>=0;j--)
            ans=(ans+f[i][j]*(j+cnt1)%mod)%mod;
        cnt1++;
    }
    ans=(ans+cnt1)%mod;
    n%=mod;
    ans=ans*n%mod;
    return ans;
}
LL cal2(LL n)
{
    LL ans=0;
    int i,j,k;
    int cnt1=0;
    for(i=len-1;i>=0;i--)
    {
        if(dig[i]==0)
            continue;
        n-=((LL)1<<i);
        ans=(ans+(n+1)%mod*mi[i]%mod*cnt1*2%mod)%mod;
        for(k=0;k<i;k++)
        {
            ans=(ans+sg[i][k]*(k+cnt1)%mod)%mod;
        }
        cnt1++;
    }
    return ans;
}
int main()
{
    LL n;
    int t,cas=1;
    scanf("%d",&t);
    init();
    while(t--)
    {
        scanf("%I64d",&n);
        len=0;
        LL tmp=n;
        while(tmp)
        {
            dig[len++]=tmp%2;
            tmp/=2;
        }
        LL ans=cal1(n);
        printf("Case #%d: %I64d\n",cas++,(ans-cal2(n)+mod)%mod);
    }
    return 0;
}


树状数组(Binary Indexed Tree),看这一篇就够了 定义 根据维基百科的定义: A Fenwick tree or binary indexed tree is a data structure that can efficiently update elements and calculate prefix sums in a table of numbers. 也就是说,所谓树状数组,或称Binary Indexed Tree,... 阅读详情

相关推荐

光耦继电器电路分析

光耦电路的分析笔记

MingYue_SSS的博客 6873

Hdu 5921 Binary Indexed Tree(长春数位dp)

题意:用树状数组维护一个序列,在给区间[l,r]加上一个t的时候,要给[1,r]加上t,给[1,l−1]减去t,两次操作后值真正发生变化的节点个数就是这一次区间修改的代价,现在要修改每一个[1,n]的子区间,求总代价 对10^​9+7取模后的结果。 #include<bits/stdc++.h> using namespace std; const int MOD=1e9+7; int dig

_zidaoziyan的博客 755

【小宁学习日记6 PCB】电路原理图

本文系统讲解了电子硬件设计中原理图的阅读与绘制技巧。首先剖析原理图的四大核心要素(元件符号、连接线、结点、注释),强调注释对可读性的重要性。然后提出三步读懂法:查看图纸信息、分模块分析、结合芯片手册验证,并列举5个典型芯片案例(CH224K、CH343P等)进行实战解析。最后给出6条绘制规范:模块化布局、详细标注、规范命名、信号流布局、符号封装匹配、版本管理。文章指出原理图是电子设计的"地基",掌握规范阅读与绘制方法能大幅提升设计效率,避免常见错误。新手应从开源项目分析和简单电路绘制入手

qq_74376834的博客 2351

Hdu-5921 Binary Indexed Tree(数位DP)

Problem Description Recently, Mr. Frog has learned binary indexed tree. Here is the code of adding t to the interval [1,x]: void add (int x, int t ){ for (int i = x; i != 0; i -= i & (-i

WZJRJ28 1120

八股文(Unity篇)

在Unity中,协程是通过迭代器实现的,即将协程函数的返回值类型定义为IEnumerator,然后使用yield语句暂停协程的执行,并在需要恢复执行时通过MoveNext()方法继续执行。Unity中的协程是一种能够在主函数中暂停和恢复执行的功能,它使用了C#的迭代器。Resources方式:Resources方式:使用Resources.Load方法加载Resources文件夹下的资源,这种方式的好处是简单易用,无需手动打包资源,但是会导致应用包变得较大,加载速度较慢,不适合较大的资源文件。

m0_50816320的博客 1万+

《Linux运维总结:etcd 3.5.15集群数据备份与恢复》

《Linux运维总结:etcd 3.5.15集群数据备份与恢复》

东城绝神 1079

Hdu 5921 Binary Indexed Tree

题解链接题意搬运: 用树状数组维护一个序列,在给区间 [l,r][l,r] 加上一个tt的时候,要给 [1,r][1,r]加上 tt,给 [1,l−1][1,l−1] 减去 tt,两次操作后值真正发生变化的节点个数就是这一次区间修改的代价,现在要修改每一个[1,n][1,n]的子区间,求总代价对 109+710^9+7取模后的结果。 题解搬运 记cnticnt_i表示ii的二进制表达式中11

lambda QAQ 1672

别再到处找教程了!Windows下用FFmpeg+Mediamtx+VLC搭建本地RTSP流媒体服务器,保姆级配置流程

本文详细介绍了在Windows系统下使用FFmpeg、Mediamtx和VLC搭建本地RTSP流媒体服务器的完整流程。从环境准备到核心配置,再到推流和拉流的实战技巧,提供了保姆级的避坑指南和优化建议,帮助开发者快速实现稳定的流媒体服务部署。

weixin_42614269的博客 212

hdu5921 Binary Indexed Tree

题目链接 把题目要求的写成下面的式子,其中fxf_xfx​为xxx的二进制中1的个数,lcp为最长公共前缀中1的个数。 ANS=∑r=0n∑l=0n(fl+fr−2flcp(l,r))2ANS=\frac{\sum\limits_{r=0}^n \sum\limits_{l=0}^{n}(f_l+f_r-2f_{lcp(l,r)})}{2}ANS=2r=0∑n​l=0∑n​(fl​+fr​−2flcp(l,r)​)​ =(n+1)∑r=1nfr−∑r=1n∑l=1n(flcp(l,r))= (n+1)\su

pubgoso的博客 271

基于Spring Boot 3 + Vue 3 + UniApp的全栈高校社团管理小程序设计与实现

requestMatchers("/api/auth/**", "/doc.html", "/webjars/**", "/v3/api-docs/**").permitAll() // 公开接口。<u-search placeholder="搜索活动" v-model="searchKeyword" @search="loadActivities" :showAction="false"></u-search>R.success("活动创建成功") : R.error("活动创建失败");

2201_76125393的博客 368

AUTOSAR从入门到精通-诊断事件管理模块(DEM)(四)

在 Autosar 中,诊断事件是指在车辆电子系统中发生的特定事件,可以用于诊断和故障排除。DEM模块通过EventId和相关的EventName来表示每个诊断事件。诊断事件的状态代表了监控器的结果,DEM模块通过RTE或其他BSW模块从SW-C接收监控器的结果。DEM模块使用EventId来管理系统中每个诊断事件的状态,并对各个测试结果执行所需的操作,例如存储冻结帧/拓展帧。所有监控器和BSW模块使用EventId作为符号化的EventName来管理诊断事件。

getusushu的博客 1508

hdu5921Binary Indexed Tree

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5921题意:给出多个n,求∑ni=1∑i−1j=0g(i,j)\sum_{i=1}^{n}\sum_{j=0}^{i-1}g(i,j),g(i,j)g(i,j)的意义是ii和jj在二进制意义下去掉公共前缀后的1的个数之和,例如11={1011},13={1101},去掉公共前缀{1100}后剩下{0011}和

Fsss 1371

【如何学习CAN总线测试】——AUTOSAR网络管理自动化测试(CAPL源码)

上一章介绍的是AUTOSAR网络管理如何测试、用例设计,对于不满足手工测试的同学,本章就介绍AUTOSAR网络管理自动化测试。

测试领域技术分享 6235

binary indexed tree

binary indexed tree背景二进制索引树(binary indexed tree [bit])是一种高效计算累积频率的“假想数据结构“,不是通所说的二叉搜索树(binary search tree)。 对一维数组A求累积频率, 常规做法如下。 更新(x, v) := A[x] += v; //O(1) 查询(x) := A[0] + A[1] + … + A[x]; //O(N)

deyangliu的专栏 560

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Hdu5921 Binary Indexed Tree

Hdu5921 Binary Indexed Tree 思路 计数问题,题目重点在于二进制下1的次数的统计,很多题解用了数位DP来辅助计算,定义g(i)表示i的二进制中1的个数, $ans = \sum_{i=1}^n \sum_{j=0}^{i-1} g(i,j) = 0.5\sum_{i=0}^n\sum_{j=0}^n[g(i)+g(j)-2g(lcp(i,j))] $ 即先计算每个位的贡献...

weixin_30488085的博客 174

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【计数】hdu5921Binary Indexed Tree

二进制拆位计算贡献 题目描述 树状数组是一种常用的数据结构,下面是树状数组用于给区间 [1,x] 内的数加 t 的代码: 1 void add(int x,int t){ 2 for (int i=x;i;i-=(i&(-i))){ 3 cnt[i]+=t; 4 } 5 } 当你要给[l,r]区间加x时,肯定是先给...

weixin_30822451的博客 223

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

树状数组(Binary Indexed Tree)

树状数组(BIT - Binary Indexed Tree)是一个用数组表示的树型数据结构,最早用于频次累计表中。树状数组中每个元素维护一个频次表A的特定部分区段的累加和。假设输入动态序列为 A,A中元素值可以被修改,如果使用直接蛮力法来查询一个区间i..j的累加和,复杂度为O(n),而树状数组由于每个元素存储的是部分累加和,通过数组 下标的二进制索引规律可以在O(logn)时间内找到1...

weixin_30478923的博客 129

ccpc 长春站 J 题 Ugly Problem

Ugly Problem Problem Description Everyone hates ugly problems. You are given a positive integer. You must represent that number by sum of palindromic numbers. A palindromic number is a positive integer such that if you write out that integer as a string

猿的进化 1354

树状数组(Binary Indexed Tree) 总结(ing)

推荐一篇很好的博客:http://www.cppblog.com/menjitianya/archive/2015/11/02/212171.html 一、树状数组的定义 基本定义:树状数组是利用二分的思想使得查询和修改的复杂度都为 log(n) 的数据结构,树状数组是通过前缀和思想,用来完成单点更新和区间查询的数据结构。 如上图,不难看出树状数组是一个不断地二分的过程。  如上图...

FFOYeah的博客 2047

树状数组 ( Binary Indexed Tree,BIT,二分索引树 )

百度很多树状数组,唯有此篇一看就懂。 原文一、简介在有时,需要计算数组某个区间内的和,如果采用常规算法,每次求和时遍历一遍求和比较耗时间,而树状数组维护一个求和数组,将原数组的一些求和结果存在数组中,使用时直接用树状数组求和。最常用的求区间和问题,单点更新。二、建树 结构: 如上A代表原数组,而C代表树状数组。树状数组具有数组和树两个特性,在存储上以数组形式按顺序存储,在逻辑关系上,通过数组下

心之所向 1668

2020CCPC长春站

2020CCPC长春站 比赛过程 一来我们分开看题,从前到后,从后到前,然后我看中间的D题。 一看感觉可以做,先上去打了个表,然后发现规律了,这时候队友说A题是签到题可以写,然后我就让出了电脑,然后我把D题跟队友说一下后修正思路确认了,然后等A题过了我就上去写D题,最后F题队友说启发式暴力合并可以过,但是需要维护一个集合的异或和,最后想到只要按位拆分01的个数维护起来就可以了,然后两个半小时得时候就过了,最后还刻了JKL三道题,最后三个人决定一起写K,然后一开始思路绕进去了,最后队友说一开始的思路是错的,这

weixin_44203780的博客 1044

Binary Indexed Tree 2D

#include #include #include #include #include using namespace std; int map[1015][1015]; void update(int x,int y, int n) { for(int i=x;i<=1005;i+=(i&(-i)))

天I火的小窝 681

2016 ccpc长春现场赛J Sequence II(hdu 5919)

Sequence II Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 466    Accepted Submission(s): 112 Problem Description Mr. Frog has a

overload1997 638

【算法笔记】Binary Indexed Tree

资料收集topcoder上的教程 上面教程的中译版 WiKi简单说说BIT尽管叫做树,但还是很难形象的把它和树联系起来。而且在初学的时候很难理解lowbit的是怎么来的,为什么要这么维护。。 其实我还是觉得能发明BIT这个东西,确实很奇妙。。。 BIT的主要用途就是维护前缀和,中心思想是用n个节点,每个节点各自负责 2r2^r长的一段连续和。对于一个节点i,r是i最低位的1的位置。 r(1

slowlight93的专栏 545

HDU 5769 Substring(后缀数组)

Substring Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1570Accepted Submission(s): 618 Problem Description ?? is practicing his prog...

weixin_30809173的博客 119
上一篇: CodeForces 427D-Match & Catch
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值