原题链接:
把十进制数转换为若干 2的k次方 的和 k则为对应层数
如 3 = 2的0次方 + 2的1次方 所以在第0层和第1层
因为ai最大为1024,所以可以开十二个线段树,套线段树板子
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int,int>pii;
const int mod = 1e9+7 , INF = 0x3f3f3f3f , N = 1e5 + 10;
struct Node
{
int l,r;
LL s;
LL add;
}tr[13][4 * N];
int n,m;
int lowbit(int x)
{
return x & -x;
}
void push_down(int u,int x)
{
Node &root = tr[u][x];
Node &left = tr[u][x << 1];
Node &right = tr[u][x << 1 | 1];
left.add += root.add;
left.s += (LL)(left.r - left.l + 1) * root.add;
right.add += root.add;
right.s += (LL)(right.r - right.l + 1) * root.add;
root.add = 0;
}
void push_up(int u,int x)
{
tr[u][x].s = tr[u][x << 1].s + tr[u][x << 1 | 1].s;
}
void build(int u,int x,int l,int r)
{
tr[u][x] = {l,r};
if (l == r)
return;
int mid = l + r >> 1;
build(u,x << 1,l,mid);
build(u,x << 1 | 1,mid + 1,r);
push_up(u,x);
}
void modify(int u,int x,int l,int r,int v)
{
if (tr[u][x].l >= l && tr[u][x].r <= r)
{
tr[u][x].s += (LL)(tr[u][x].r - tr[u][x].l + 1) * v;
tr[u][x].add += v;
}
else
{
push_down(u,x);
int mid = tr[u][x].l + tr[u][x].r >> 1;
if (l <= mid)
modify(u,x << 1,l,r,v);
if (r > mid)
modify(u,x << 1 | 1,l,r,v);
push_up(u,x);
}
}
LL query(int u,int x,int l,int r)
{
if (tr[u][x].l >= l && tr[u][x].r <= r)
return tr[u][x].s;
push_down(u,x);
int mid = tr[u][x].l + tr[u][x].r >> 1;
LL res = 0;
if (l <= mid)
res = query(u,x << 1,l,r);
if (r > mid)
res += query(u,x << 1 | 1,l,r);
return res;
}
int main()
{
cin >> n >> m;
for (int i = 0 ; i <= 12 ; i ++)
build(i,1,1,n);
while (m --)
{
int type;
cin >> type;
if (type == 1)
{
int x,l,r,c;
cin >> x >> l >> r >> c;
while (x)
{
modify(log2(lowbit(x)),1,l,r,c);
x -= lowbit(x);
}
}
else
{
int x,l,r;
cin >> x >> l >> r;
LL res = 0;
while (x)
{
res += query(log2(lowbit(x)),1,l,r);
x -= lowbit(x);
}
cout << res << endl;
}
}
}