Krypton binary

Keywords: Algorithm data structure acm

Binary

Title Description

You are an algorithm enthusiast, trying to learn computer knowledge. You know, the most beautiful part of the computer is binary, which you have a deep experience in shape pressure plus o. of course, binary is also very clever when used in co and o, not to mention that nini games can be related to xor. T oday, you encounter a binary problem. For you who love thinking, you decide to cut off this binary problem all the time.
You encounter many decimal numbers. For these numbers, they manage their corresponding layers. For example, the number 8, whose binary is 1, manages 4 (10), 2 (10) and two segments. When the number increases in the interval of 2 and 4, foam represents that the binary (10) and (10) layers increase by 3 in the interval of [2,4].
This question has two operations. Read in an opt
When opt is 1: read in a number qi, an interval li, ri and an increased value ki, indicating that the value of ki is increased in each interval in the hierarchy managed by this number.
When opt is 2: read in a number ai and an interval li,ri, indicating the sum of the values of each interval in the hierarchy managed by this number.

input

In the first line, there are two integers n,q, indicating that n represents the interval length (1 ≤ li ≤ ri ≤ n ≤ 100000), and q represents q(1 ≤ q ≤ 100000) operations. Data assurance (1 ≤ ai ≤ 1024),ki within int
In the following q lines, the first number opt in each line indicates the operation
When opt= 1, followed by the integer ai represents the management hierarchy, li,ri represents the interval, ki represents the increased value, and when opt= 2, followed by the integer ai represents the management hierarchy, li,ri represents the interval

output

For each second operation, output a line representing the answer to the query.

Sample Input

5 3
1 3 1 5 2
2 1 1 2
2 3 1 2

Sample Output

4
8

Train of thought analysis

Open a 12 segment tree. Don't ask why it is 12. I don't want to card the boundary.
Then detect the sequence number whose binary bit is 1, put it on the stack (queue), and then maintain the segment tree of the sequence number in turn.
Finally, when reading, query the segment tree of all serial numbers, and find a sum.

Accepted Code

//#include<unordered_map>
#include<algorithm>
#include<iostream>
#include<string.h>
#include <iomanip>
#include<stdio.h>
#include<vector>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const ll less_inf = 0x3f3f3f3f;
const char char_inf = 127;
#pragma GCC optimize(2)
#define accelerate cin.tie(NULL);cout.tie(NULL);ios::sync_with_stdio(false);
#define PI 3.141592653589793
#define EPS 1.0e-8
ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}
ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}
inline ll read() {
	ll c = getchar(), Nig = 1, x = 0;
	while (!isdigit(c) && c != '-')c = getchar();
	if (c == '-')Nig = -1, c = getchar();
	while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
	return Nig * x;
}
inline void out(ll a) {
	if (a < 0)putchar('-'), a = -a;
	if (a > 9)out(a / 10);
	putchar(a % 10 + '0');
}
ll qpow(ll x, ll n, ll mod) {
	ll res = 1;
	while (n > 0) {
		if (n & 1)res = (res * x) % mod;
		x = (x * x) % mod;
		n >>= 1;
	}
	return res;
}
#define read read()
const int N = 100007;
struct node
{
	ll sum, num;
	bool lazy;
}tree[12][N << 2];
void pushup(int k, int rt)
{
	tree[k][rt].sum = tree[k][rt << 1].sum + tree[k][rt << 1|1].sum;
}
void pushdown(int k, int len, int rt)
{
	if (tree[k][rt].lazy)
	{
		tree[k][rt << 1].lazy = tree[k][rt << 1 | 1].lazy = true;
		tree[k][rt].lazy = false;
		tree[k][rt << 1].num += tree[k][rt].num;
		tree[k][rt << 1 | 1].num += tree[k][rt].num;
		tree[k][rt << 1].sum += tree[k][rt].num * (len - (len >> 1));
		tree[k][rt << 1 | 1].sum += tree[k][rt].num * (len >> 1);
		tree[k][rt].num = 0;
	}
}
void update(int L, int R, ll val, int k, int l, int r, int rt)
{
	if (L <= l && r <= R)
	{
		tree[k][rt].lazy = true;
		tree[k][rt].num += val;
		tree[k][rt].sum += (r - l + 1) * val;
		return;
	}
	pushdown(k, r - l + 1, rt);
	int mid = l + r >> 1;
	if (L <= mid)update(L, R, val, k, l, mid, rt << 1);
	if (R >= mid + 1)update(L, R, val, k, mid + 1, r, rt << 1 | 1);
	pushup(k, rt);
}
ll query(int L, int R, int k, int l, int r, int rt)
{
	if (L <= l && r <= R)return tree[k][rt].sum;
	pushdown(k, r - l + 1, rt);
	int mid = l + r >> 1;
	ll res = 0;
	if (L <= mid)res += query(L, R, k, l, mid, rt << 1);
	if (R > mid)res += query(L, R, k, mid + 1, r, rt << 1 | 1);
	return res;
}
stack<ll>s;
int main()
{
	accelerate;
	int n, m;
	cin >> n >> m;
	while (m--)
	{
		ll mark, id;
		cin >> mark >> id;
		if (mark == 1)
		{
			for (ll i = 1, cnt = 0; i <= 1024; i <<= 1, cnt++)
				if (i & id)s.push(cnt);
			ll l, r, val;
			cin >> l >> r >> val;
			while (!s.empty())
			{
				ll now = s.top();
				s.pop();
				update(l, r, val, now, 1, n, 1);
			}
		}
		else
		{
			for (ll i = 1, cnt = 0; i <= 1024; i <<= 1, cnt++)
				if (i & id)s.push(cnt);
			ll ans = 0;
			ll l, r;
			cin >> l >> r;
			while (!s.empty())
			{
				ll now = s.top();
				s.pop();
				ans += query(l, r, now, 1, n, 1);
			}
			cout << ans << endl;
		}
	}
}

By-Round Moon

Posted by Rigo on Sun, 24 Oct 2021 00:55:43 -0700