Today, Rikka is going to learn how to use BIT to solve some simple data structure tasks. While studying, She finds there is a magic expression in the template of BIT. After searching for some literature, Rikka realizes it is the implementation of the function .
is defined on all positive integers. Let a1...am be the binary representation of x while a1 is the least significant digit, k be the smallest index which satisfies ak = 1. The value of is equal to 2k-1.
After getting some interesting properties of , Rikka sets a simple data structure task for you:
At first, Rikka defines an operator f(x), it takes a non-negative integer x. If x is equal to 0, it will return 0. Otherwise it will return or , each with the probability of .
Then, Rikka shows a positive integer array A of length n, and she makes m operations on it.
There are two types of operations:
1. 1 L R, for each index i ∈ [L,R], change Ai to f(Ai).
2. 2 L R, query for the expectation value of . (You may assume that each time Rikka calls f, the random variable used by f is independent with others.)
输入描述:
The first line contains a single integer t(1 ≤ t ≤ 3), the number of the testcases. The first line of each testcase contains two integers n,m(1 ≤ n,m ≤ 105). The second line contains n integers Ai(1 ≤ Ai ≤ 108). And then m lines follow, each line contains three integers t,L,R(t ∈ {1,2}, 1 ≤ L ≤ R ≤ n).
输出描述:
For each query, let w be the expectation value of the interval sum, you need to output . It is easy to find that w x 2nm must be an integer.
输入
1 3 6 1 2 3 1 3 3 2 1 3 1 3 3 2 1 3 1 1 3 2 1 3
输出
1572864 1572864 1572864
加和减概率相同,加减的数也相同所以不变
函数f(x)它的值有一半概率是x - lowbit(x),一半概率是x + lowbit(x)
树状数组
#include<bits/stdc++.h>
using namespace std;
#define mod 998244353
long long wwf(long long a, long long b)
{
long long ans = 1;
a %= mod;
while (b) {
if (b & 1)ans = ans * a%mod;
a = a * a%mod;
b >>= 1;
}
return ans;
}
int main()
{
long long t,n,m,b,c,l,r,d,a[100005];
long long ans=0,w,we;
cin>>t;
while(t--) {
scanf("%lld %lld",&n,&m);
ans=wwf(2,n*m);
a[0]=0;
for(int i=1;i<=n;i++){
scanf("%lld",&c);
a[i]=a[i-1]+c;
}
for(int i=0;i<m;i++){
scanf("%lld %lld %lld",&d,&l,&r);
if(d==2){
we=a[r]-a[l-1]+mod;
we%=mod;
printf("%lld\n",we*ans%mod);
}
}
}
}