萌新求条线段树(玄关)
查看原帖
萌新求条线段树(玄关)
463956
incra楼主2024/10/18 12:19

目前已知加了最后的任意一行注释后阳历答案就正确了。

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cassert>
#include <chrono>
#include <random>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define pf push_front
#define desktop "C:\\Users\\MPC\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
int fastio = (IOS,0);
// #define endl '\n'
#define puts(s) cout << s << endl
const int N = 50010,MOD = 19940417;
int n,m;
int a[N];
int C[N][25];
LL pw[25];
struct node {
	int l,r;
	LL ans[25];
	LL add;
	bool rev;
}tr[4 * N];
void push_up (node &rt,node l,node r) {
	memset (rt.ans,0,sizeof (rt.ans));
	for (int i = 0;i <= min (l.r - l.l + 1,20);i++) {
		for (int j = 0;j <= min (r.r - r.l + 1,20 - i);j++) rt.ans[i + j] = (rt.ans[i + j] + l.ans[i] * r.ans[j] % MOD) % MOD;
	}
}
void push_up (int u) {
	push_up (tr[u],tr[u << 1],tr[u << 1 | 1]);
}
void opt_rev (int u) {
	for (int i = 1;i <= min (tr[u].r - tr[u].l + 1,20);i++) tr[u].ans[i] = i % 2 ? (MOD - tr[u].ans[i]) % MOD : tr[u].ans[i];
	tr[u].add = (MOD - tr[u].add) % MOD;
	tr[u].rev ^= 1;
}
void opt_add (int u,LL d) {
	pw[0] = 1;
	for (int i = 1;i <= min (tr[u].r - tr[u].l + 1,20);i++) pw[i] = pw[i - 1] * d % MOD;
	for (int i = min (tr[u].r - tr[u].l + 1,20);i >= 1;i--) {
		for (int j = 0;j < i;j++) tr[u].ans[i] = (tr[u].ans[i] + tr[u].ans[j] * pw[i - j] % MOD * C[tr[u].r - tr[u].l + 1 - j][i - j]) % MOD;
	}
	tr[u].add = (tr[u].add + d) % MOD;
}
void push_down (int u) {
	if (tr[u].rev) {
		opt_rev (u << 1),opt_rev (u << 1 | 1);
		tr[u].rev = 0;
	}
	if (tr[u].add) {
		opt_add (u << 1,tr[u].add),opt_add (u << 1 | 1,tr[u].add);
		tr[u].add = 0;
	}
}
void build (int u,int l,int r) {
	tr[u] = {l,r,{1,(a[l] % MOD + MOD) % MOD},0,0};
	if (l == r) return ;
	int mid = l + r >> 1;
	build (u << 1,l,mid),build (u << 1 | 1,mid + 1,r);
	push_up (u);
}
void modify_add (int u,int l,int r,LL d) {
	if (l <= tr[u].l && tr[u].r <= r) {
		opt_add (u,d);
		return ;
	}
	push_down (u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) modify_add (u << 1,l,r,d);
	if (r >= mid + 1) modify_add (u << 1 | 1,l,r,d);
	push_up (u);
}
void modify_rev (int u,int l,int r) {
	if (l <= tr[u].l && tr[u].r <= r) {
		opt_rev (u);
		return ;
	}
	push_down (u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) modify_rev (u << 1,l,r);
	if (r >= mid + 1) modify_rev (u << 1 | 1,l,r);
	push_up (u);
}
node query (int u,int l,int r) {
	if (l <= tr[u].l && tr[u].r <= r) return tr[u];
	push_down (u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (r <= mid) return query (u << 1,l,r);
	if (l >= mid + 1) return query (u << 1 | 1,l,r);
	node ans;
	memset (ans.ans,0,sizeof (ans.ans));
	ans.rev = ans.add = 0;
	push_up (ans,query (u << 1,l,r),query (u << 1 | 1,l,r));
	return ans;
}
int main () {
	cin >> n >> m;
	for (int i = 1;i <= n;i++) cin >> a[i];
	for (int i = 0;i <= n;i++) {
		C[i][0] = 1;
		for (int j = 1;j <= min (i,20);j++) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
	}
	build (1,1,n);
	while (m--) {
		char op;
		cin >> op;
		if (op == 'I') {
			int l,r,c;
			cin >> l >> r >> c;
			c = (c % MOD + MOD) % MOD;
			modify_add (1,l,r,c);
		}
		else if (op == 'R') {
			int l,r;
			cin >> l >> r;
			modify_rev (1,l,r);
		}
		else {
			int l,r,x;
			cin >> l >> r >> x;
			cout << query (1,l,r).ans[x] % MOD << endl;
			// for (int i = 1;i <= n;i++) cout << query (1,i,i).ans[1] << ' ';
			// cout << endl;
		}
	}
	return 0;
}
2024/10/18 12:19
加载中...