蒟蒻线段树求调
  • 板块灌水区
  • 楼主MLsy
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/10/24 14:42
  • 上次更新2023/10/24 15:38:37
查看原帖
蒟蒻线段树求调
700552
MLsy楼主2023/10/24 14:42

P4247

全部WA

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MOD = 19940417;

template <typename T>
inline void read(T &ans)
{
	char ch = getchar();
	int f = 1;
	ans = 0;
	for (; !isdigit(ch); ch = getchar())
		ch == '-' ? f = -1 : f = 1;
	for (; isdigit(ch); ch = getchar())
		ans = (ans << 3) + (ans << 1) + (ch & 15);
	ans *= f;
	return;
}
template <typename T, typename... Args>
inline void read(T &tmp, Args &...tmps)
{
	read(tmp);
	read(tmps...);
}

template <class T>
inline void print(T ret, int flg = 0)
{
	static int sta[35];
	T x = ret;
	int top = 0;
	bool f = (ret < 0);
	if (ret < 0)
		x = -x;
	do
	{
		sta[top++] = x % 10, x /= 10;
	} while (x);
	if (f)
		putchar('-');
	while (top)
		putchar(sta[--top] + 48);
	if (flg == 0)
		putchar(' ');
	else if (flg == 1)
		putchar('\n');
}

int C[50010][21], a[50010];
int n, m;

struct tree
{
	int size;
	int c[21];
	int add;
	int f;
} t[50010 << 2];


inline void pushup(int rt)
{
	memset(t[rt].c, 0, sizeof(t[rt].c));
	for (int i = 0; i <= t[rt << 1].size && i <= 20; ++i)
		for (int j = 0; i + j <= 20 && j <= t[rt << 1 | 1].size; ++j)
			t[rt].c[i + j] = (t[rt].c[i + j] + t[rt << 1].c[i] * t[rt << 1 | 1].c[j] % MOD) % MOD;
}


inline void build(int rt, int l, int r)
{
	t[rt].size = r - l + 1;
	if (l == r)
	{
		t[rt].c[0] = 1;
		t[rt].c[1] = (a[l] % MOD + MOD) % MOD;
		return;
	}
	int mid = (l + r) >> 1;
	build(rt << 1, l, mid);
	build(rt << 1 | 1, mid + 1, r);
	pushup(rt);
}


inline void puad(int q, int x)
{
	if (!q || !x)
		return;
	int tmp[50];
	tmp[0] = 1;
	for (int i = 1; i <= 20 && i <= t[q].size; i++)
		tmp[i] = tmp[i - 1] * x % MOD;
	for (int i = min((int)20, t[q].size); i != 0; i--)
		for (int j = 0; j < i; j++)
			t[q].c[i] = (t[q].c[i] + t[q].c[j] * tmp[i - j] % MOD * C[t[q].size - j][i - j]) % MOD;
	t[q].add = (t[q].add + x) % MOD;
}


inline void pure(int q)
{
	if (!q)
		return;
	for (int i = 1; i <= 20 && i <= t[q].size; i++)
	{
		if (i % 2)
			t[q].c[i] = MOD - t[q].c[i];
		else
			continue;
	}
	t[q].f ^= 1;
	t[q].add = MOD - t[q].add;
}

inline tree change(tree a, tree b)
{
	tree res;
	res.size = a.size + b.size;
	memset(res.c, 0, sizeof(res.c));
	for (int i = 0; i <= (int)20 && i <= a.size; ++i)
		for (int j = 0; j + i <= (int)20 && j <= b.size; ++j)
			res.c[i + j] = (res.c[i + j] + a.c[i] * b.c[j] % MOD) % MOD;
	return res;
}

inline void pushdown(int rt)
{
	if (t[rt].f)
	{
		pure(rt << 1);
		pure(rt << 1 | 1);
		t[rt].f = 0;
	}
	if (t[rt].add)
	{
		puad(rt << 1, t[rt].add);
		puad(rt << 1 | 1, t[rt].add);
		t[rt].add = 0;
	}
}

inline void upd(int rt, int l, int r, int ql, int qr, int v)
{
	if (l > qr || r < ql)
		return;
	if (l >= ql && r <= qr)
	{
		puad(rt, v);
		return;
	}
	pushdown(rt);
	int mid = (l + r) >> 1;
	upd(rt << 1, l, mid, ql, qr, v);
	upd(rt << 1 | 1, mid + 1, r, ql, qr, v);
	pushup(rt);
}

inline tree qry(int rt, int l, int r, int ql, int qr)
{
	if (l >= ql && r <= qr)
		return t[rt];
	pushdown(rt);
	int mid = (l + r) >> 1;
	if (qr <= mid)
		return qry(rt << 1, l, mid, ql, qr);
	else if (ql > mid)
		return qry(rt << 1 | 1, mid + 1, r, ql, qr);
	else
		return change(qry(rt << 1, l, mid, ql, qr), qry(rt << 1 | 1, mid + 1, r, ql, qr));
}

inline void rev(int rt, int l, int r, int ql, int qr)
{
	if (l > qr || r < ql)
		return;
	if (l >= ql && r <= qr)
	{
		pure(rt);
		return;
	}
	pushdown(rt);
	int mid = (l + r) >> 1;
	rev(rt << 1, l, mid, ql, qr);
	rev(rt << 1 | 1, mid + 1, r, ql, qr);
	pushup(rt);
}

inline void init()
{
	t[0].c[0] = 1;
	for (int i = 1; i <= n; ++i)
	{
		C[i][0] = 1;
		for (int j = 1; j <= i && j <= 20; ++j)
			C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
	}
}

signed main()
{
	read(n, m);
	C[0][0] = 1;
	init();
	for (int i = 1; i <= n; ++i)
		read(a[i]);
	build(1, 1, n);
	for (int i = 1; i <= m; ++i)
	{
		char op = getchar();
		while (op ^ 'I' && op ^ 'R' && op ^ 'Q')
			op = getchar();
		if (op == 'I')
		{
			int a, b, c;
			read(a, b, c);
			upd(1, 1, n, a, b, c);
		}
		else if (op == 'R')
		{
			int a, b;
			read(a, b);
			rev(1, 1, n, a, b);
		}
		else
		{
			int a, b, c;
			read(a, b, c);
			tree res = qry(1, 1, n, a, b);
			if (res.c[c] < 0)
				print((MOD - res.c[c]));
			else
				print(res.c[c] % MOD);
			putchar('\n');
		}
	}
	return 0;
}

2023/10/24 14:42
加载中...