全WA求助
查看原帖
全WA求助
195388
alvis楼主2021/9/5 16:44

RT,样例过了,但是不知道为什么全WA

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

const int N = 50010, P = 19940417;
int n, m;
int a[N], C[N][21];

struct node {
	int sz, c[21];
	int ad, f;
}t[N << 2], Empty;

bool operator == (node a, node b) {
	return a.sz == b.sz && a.c[0] == b.c[0];
}
//预处理C数组(组合数)
void init() {
	t[0].c[0] = 1;
	C[0][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]) % P;
		}
	}
	Empty.c[0] = -1; 
	Empty.sz = 0;
}
//修改
void update(int q) {
	memset(t[q].c, 0, sizeof t[q].c);
	for(int i = 0;i <= t[q << 1].sz && i <= 20;i ++) {
		for(int j = 0;i+j <= 20 && j <= t[q << 1|1].sz;j ++) {
			t[q].c[i+j] = (t[q].c[i+j] + t[q << 1].c[i] * t[q << 1|1].c[j] % P) % P;
		}
	}
}
//建树
void build(int q, int l, int r) {
	t[q].sz = (r - l + 1);
	if(l == r) {
		t[q].c[0] = 1;
		t[q].c[1] = (a[l]%P + P) % P;
		return ;
	} 
	int mid = l+r >> 1;
	build(q << 1, l, mid);
	build(q << 1|1, mid+1, r);
	update(q);
}
//加数的操作
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].sz;i ++) tmp[i] = tmp[i-1] * x % P;
	for(int i = min((int)20, t[q].sz);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] % P * C[t[q].sz - j][i-j] ) % P;
		}
	}
	t[q].ad = (t[q].ad + x) % P;
}
//取相反数的操作
void pure(int q){
	if(!q) return ;
	for(int i = 1;i <= 20 && i <= t[q].sz;i ++) {
		if(i % 2) t[q].c[i] = P - t[q].c[i];
		else continue;
	}
	t[q].f ^= 1;
	t[q].ad = P - t[q].ad;
}
//下穿标记
void pushdown(int q) {
	if(t[q].f) {
		pure(q << 1);
		pure(q << 1|1);
		t[q].f = 0;
	} 
	if(t[q].ad) {
		puad(q << 1, t[q].ad);
		puad(q << 1|1, t[q].ad);
		t[q].ad = 0;
	}
}
//加一个数
void add(int q, int stl, int str, int l, int r, int x) {
	if(stl > r || str < l) return;
	if(stl >= l && str <= r) {
		puad(q, x);
		return ;
	}
	pushdown(q);
	int mid = str + stl >> 1;
	add(q<<1, stl, mid, l, r, x);
	add(q<<1|1, mid+1, str, l, r, x);
	update(q);
}
//区间取相反数
void rev(int q, int stl, int str, int l, int r) {
	if(stl > r || str < l) return;
	if(stl >= l && str <= r) {
		pure(q);
		return ;
	}
	pushdown(q);
	int mid = str + stl >> 1;
	rev(q<<1, stl, mid, l, r);
	rev(q<<1|1, mid+1, str, l, r);
	update(q);
}
//合并两个区间
node merge(node a, node b) {
	node e;
	e.sz = a.sz + b.sz;
	memset(e.c, 0, sizeof e.c);
	for(int i = 0;i <= (int)20 && i <= a.sz;i ++) {
		for(int j = 0;j <= b.sz && i+j <= (int)20;j ++) {
			e.c[i+j] = (e.c[i+j] + a.c[i] * b.c[j] % P) % P;
		} 
	}
	return e;
}
//查询操作
node query(int q, int stl, int str, int l, int r) {
	if(stl >= l && str <= r) {
		return t[q];
	}
	pushdown(q);
	int mid = stl+ str >> 1;
	if(r <= mid) return query(q << 1, stl, mid, l, r);
	else if(l > mid) return query(q << 1|1, mid+1, str, l, r);
	else return merge(query(q << 1, stl, mid, l, r), query(q << 1|1, mid+1, str, l, r));
}

signed main() {
	cin >> n >> m;
	for(int i = 1;i <= n;i ++) {
		cin >> a[i];
	}
	init();
	build(1, 1, n);
	while(m --) {
		char op;
		cin >> op;
		if(op == 'I') {
			int a, b, c;
			cin >> a >> b >> c;
			add(1, 1, n, a, b, c);
		}
		if(op == 'R') {
			int a, b;
			cin >> a >> b;
			rev(1, 1, n, a, b);
		}
		if(op == 'Q') {
			int a, b, c;
			cin >> a >> b >> c;
			node e = query(1, 1, n, a, b);
			if(e.c[c] < 0) cout << P - e.c[c] << endl;
			else cout << e.c[c] % P << endl;
		}
	}
	
	return 0;
} 
2021/9/5 16:44
加载中...