社区讨论

求助分块

P3373【模板】线段树 2参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@miiunhsq
此快照首次捕获于
2025/11/28 20:39
3 个月前
此快照最后确认于
2025/11/29 17:30
3 个月前
查看原帖
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
	int x = 0,p = 1;
	char c = getchar();
	while(c > '9' || c < '0')	p = c == '-' ? -1 : 1,c = getchar();
	while(c >= '0' && c <= '9')	x = (x << 1) + (x << 3) + (c ^ 48),c = getchar();
	return p * x;
}
template<typename _Tp> void _write(_Tp x) { if(x > 9) _write(x / 10); putchar(x % 10 | 48); }
template<typename _Tp> void write(_Tp x) { if(x < 0) putchar('-'),x = -x; _write(x); }
template<typename _Tp> void writeln(_Tp x) { write(x); puts(""); }
#define mod (long long)(1e9 + 7)
const int N = 1e5 + 10;
const int M = 1e3 + 10;
int n,m,q,L,a[N],b[N],l[M],r[M],len[M],bs[M];
struct lazytag { int k,b; };
lazytag tag[M],t;
inline void init() { t = (lazytag){1,0}; }
inline lazytag operator + (lazytag x,int k)
{
	(x.b += k) %= m;
	return x;
}
inline lazytag operator * (lazytag x,int k)
{
	(x.k *= k) %= m; (x.b *= k) %= m;
	return x;
}
inline int calc(int y,lazytag x) { return (x.k * y % m + x.b) % m; }
inline void pushdown(int p)
{
	if(tag[p].k == t.k && tag[p].b == t.b)	return;
	for(int i = l[p];i <= r[p];i++)
	{
		bs[p] -= a[i];
		bs[p] %= m;
		a[i] = calc(a[i],tag[p]);
		bs[p] += a[i];
		bs[p] %= m;
		(bs[p] += m) %= m;
	}
	tag[p] = t;
}
inline void add(int L,int R,int k)
{
	if(b[L] != b[R])
	{
		pushdown(b[L]); pushdown(b[R]);
		for(int i = L;b[L] == b[i];i++)	(a[i] += k) %= m,(bs[b[i]] += k) %= m;
		for(int i = R;b[R] == b[i];i--)	(a[i] += k) %= m,(bs[b[i]] += k) %= m;
		for(int i = b[L] + 1;i <= b[R] - 1;i++)	tag[i] = tag[i] + k;
	}
	else
	{
		pushdown(b[L]);
		for(int i = L;i <= R;i++)	(a[i] += k) %= m,(bs[b[i]] += k) %= m;
	}
}
inline void mul(int L,int R,int k)
{
	if(b[L] != b[R])
	{
		pushdown(b[L]); pushdown(b[R]);
		for(int i = L;b[L] == b[i];i++)	bs[b[i]] -= a[i],(a[i] *= k) %= m,(bs[b[i]] += a[i]) %= m,(bs[b[i]] += m) %= m;
		for(int i = R;b[R] == b[i];i--)	bs[b[i]] -= a[i],(a[i] *= k) %= m,(bs[b[i]] += a[i]) %= m,(bs[b[i]] += m) %= m;
		for(int i = b[L] + 1;i <= b[R] - 1;i++)	tag[i] = tag[i] * k;
	}
	else
	{
		pushdown(b[L]);
		for(int i = L;i <= R;i++)	bs[b[i]] -= a[i],(a[i] *= k) %= m,(bs[b[i]] += a[i]) %= m,(bs[b[i]] += m) %= m;
	}
}
inline int query(int L,int R)
{
	int ans = 0;
	if(b[L] != b[R])
	{
		pushdown(b[L]); pushdown(b[R]);
		for(int i = L;b[L] == b[i];i++)	(ans += a[i]) %= m;
		for(int i = R;b[R] == b[i];i--)	(ans += a[i]) %= m;
		for(int i = b[L] + 1;i <= b[R] - 1;i++)	(ans += bs[i] * tag[i].k % m + tag[i].b * len[i] % m) %= m;
	}
	else
	{
		pushdown(b[L]);
		for(int i = L;i <= R;i++)	(ans += a[i]) %= m;
	}
	return ans;
}
signed main()
{
	n = read(); q = read(); m = read(); L = sqrt(n);
	init();
	for(int i = 1;i <= n;i++)	a[i] = read();
	for(int i = 1;i <= n;i++)	b[i] = (i - 1) / L + 1;
	for(int i = 1;i <= n;i++)	(bs[b[i]] += a[i]) %= m;
	memset(l,0x3f,sizeof(l));
	for(int i = 1;i <= n;i++)	l[b[i]] = min(l[b[i]],i);
	for(int i = 1;i <= n;i++)	r[b[i]] = i;
	for(int i = 1;i <= n;i++)	len[b[i]] = r[b[i]] - l[b[i]] + 1;
	for(int i = 1;i <= b[n];i++)	tag[i] = t;
	int op,x,y,k;
	while(q--)
	{
		op = read(); x = read(); y = read();
		if(op == 1)
		{
			k = read();
			mul(x,y,k);
		}
		else if(op == 2)
		{
			k = read();
			add(x,y,k);
		}
		else	writeln(query(x,y)); 
	}
	return 0;
}
以上分块为什么只有 70 pts。
提交记录
帮忙看一下

回复

3 条回复,欢迎继续交流。

正在加载回复...