http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=832
Problem Description
In the world line 1.048596%
双叶理央是梓川咲太为数不多的朋友。
栖息于理科实验室,一直在做着梓川咲太永远也想不明白的实验。偶尔用半升的烧杯煮咖啡,度过悠闲的校园时光。
梓川咲太无聊的时候也经常拜访理科实验室。黄金周的最后一天,上午,双叶理央也在辛勤的做着实验,不过这次有点不同,并没有常识中的实验仪器,双叶理央面对电脑陷入深思。
“你来的正好,听我说。”,双叶理央罕见的没有先让梓川咲太出去,“我最近在用Binary Indexed Tree去解决一个有关数据结构的问题,里面有一个语句是x&(-x),这是对方程lowbit(x)的模拟操作。”
梓川咲太想吐槽些什么,可是立刻被双叶理央递过来的咖啡堵住了嘴。
“听我说完,lowbit(x)的含义为x的二进制表达式中,最低位1所对应的值,比如说6的二进制为110,所以lowbit(6)=2。”
感觉说的不够详细的理央整理了一下思绪,继续说道。
“更一般的,设 a[m],a[m-1].....a[1]是数x的二进制表示,而a[m]是x二进制的最低位,k是最小的满足a[k]=1的下标。则此时,lowbit(x)的值就等于 2^(k-1)。”
"恩恩,是这样吗,我懂了。"
梓川咲太什么都听不懂。
“现在有这么一个操作,就称为f(x)吧。当输入一个非负整数x,如果x等于0,则返回0;否则他有二分之一的概率会返回x-lowbit(x),也有二分之一的概率的记录返回x+lowbit(x)。”
双叶理央开始在黑板上写下数学公式。
“现在有一个长度为n的数组A,我会对它进行m次操作。
操作有两种,第一种是1 L R,对于每一个下标i属于[L,R],将Ai变为f(Ai)。
第二种是 2 L R,询问在区间[L,R],Ai的值的期望值的总和。”
“当然,这些操作对于每一个f(Ai)操作都是独立的,不会影响其他的部分的结果......”
双叶理央说完以后开始陷入深思,没过多久就展现出茅塞顿开的表情。
“......大概就是这样,也不是什么难题......笨蛋梓川果然是当小黄鸭的最好人选。行了,你快滚出去吧。”
梓川咲太很自觉的离开了理科实验室。
之后,梓川咲太骑车去湘南台站附近的图书馆,给妹妹梓川枫借还书的时候,『那个』进入了视线。
野兔先辈屹立在书架的彼岸。
这一天,梓川咲太与野兔先辈邂逅了。
Input
第一行一个整数T,表示有T组样例
对于每组样例
第一行两个整数n,m(1<=n,m<=1e5),表示数组的长度n与操作的次数m
第二行n个整数Ai(1<=Ai<=1e4),表示数组每个的数字
之后的m行,每一行有三个整数 t,L,R(t==1 或 t==2,1<=L<=R<=n ).
输入保证n和m的和不超过1e6。
Output
对于每一组询问操作,输出对应区间的Ai的值的期望得分的值。
Sample Input
1 3 2 1 2 3 1 3 3 2 1 2
Sample Output
3
Hint
Scanf Recommed
C++版本一
/*
*@Author: STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
using namespace std;
typedef long long ll;
const int N=100000+10;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m;
int tree[N<<2];
void PushUp(int rt){
tree[rt] = tree[rt*2] + tree[rt*2+1];
}
void Build(int l, int r, int rt){
if(l == r){
scanf("%d",&tree[rt]);
return ;
}
int m = (l+r) / 2;
Build(l,m,rt*2);
Build(m+1,r,rt*2+1);
PushUp(rt);
}
int Query(int l, int r, int rt, int L, int R){
if(L <= l && r <= R){
return tree[rt];
}
int m = (l+r) / 2;
int ret = 0;
if(L <= m) ret += Query(l, m, rt*2, L, R);
if(m < R) ret += Query(m+1, r, rt*2+1, L, R);
return ret;
}
int main()
{
#ifdef DEBUG
freopen("input.in", "r", stdin);
//freopen("output.out", "w", stdout);
#endif
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
Build(1,n,1);
int T,l,r;
while(m--){
scanf("%d%d%d",&T,&l,&r);
if(T==1){
}else{
printf("%d\n", Query(1,n,1,l,r));
}
}
}
//cout << "Hello world!" << endl;
return 0;
}
C++版本二
https://www.cnblogs.com/MingSD/p/10050324.html
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+7;
const int N = 1e5 + 100;
int a[N];
int main(){
int n, m, T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]), a[i] += a[i-1];
int op, l, r;
while(m--){
scanf("%d%d%d", &op, &l, &r);
if(op == 2){
printf("%d\n", a[r] - a[l-1]);
}
}
}
return 0;
}