分块超时 10ms 求助
查看原帖
分块超时 10ms 求助
804607
rainygame楼主2023/8/15 19:37

是复杂度错了还是常数问题?

代码:

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

int uread(){
    int x(0);
    char ch;
    while ((ch = getchar()) < 48);
    do{
        x = (x << 1) + (x << 3) + (ch ^ 48);
    }while ((ch = getchar()) > 47);
    return x;
}

int n, m, mod, opt, l, r, k, len, tot;
int a[MAXN], bl[MAXN];
int L[MAXM], R[MAXM];
int sum[MAXM], add[MAXM], mul[MAXM];

void init(){
	len = sqrt(n);
	tot = (n-1)/len+1;
	for (int i(1); i<=tot; ++i){
		L[i] = R[i-1] + 1;
		R[i] = i * len;
	}
	R[tot] = n;
	
	for (int i(1); i<=tot; ++i){
		for (int j(L[i]); j<=R[i]; ++j){
			bl[j] = i;
			sum[i] += a[j];
		}
		mul[i] = 1;
	}
}

void push_up(int x){
	sum[x] = 0;
	for (int i(L[x]); i<=R[x]; ++i) sum[x] += a[i];
}

void push_down(int x){
	for (int i(L[x]); i<=R[x]; ++i) a[i] = (a[i] * mul[x] + add[x]) % mod;
	mul[x] = 1;
	add[x] = 0;
}

void upd1(int l, int r, int c){
	int p(bl[l]), q(bl[r]);
	if (p == q){
		push_down(p);
		for (int i(l); i<=r; ++i) a[i] = (a[i] + c) % mod;
		push_up(p);
		return;
	}
	
	push_down(p);
	for (int i(l); i<=R[p]; ++i) a[i] = (a[i] + c) % mod;
	push_up(p);
	for (int i(p+1); i<q; ++i){
		add[i] = (add[i] + c) % mod;
		sum[i] = (sum[i] + len * c) % mod;
	}
	push_down(q);
	for (int i(L[q]); i<=r; ++i) a[i] = (a[i] + c) % mod;
	push_up(q);
}

void upd2(int l, int r, int c){
	int p(bl[l]), q(bl[r]);
	if (p == q){
		push_down(p);
		for (int i(l); i<=r; ++i) a[i] = (a[i] * c) % mod;
		push_up(p);
		return;
	}
	
	push_down(p);
	for (int i(l); i<=R[p]; ++i) a[i] = (a[i] * c) % mod;
	push_up(p);
	for (int i(p+1); i<q; ++i){
		add[i] = (add[i] * c) % mod;
		mul[i] = (mul[i] * c) % mod;
		sum[i] = (sum[i] * c) % mod;
	}
	push_down(q);
	for (int i(L[q]); i<=r; ++i) a[i] = (a[i] * c) % mod;
	push_up(q);
}

int query(int l, int r){
	int p(bl[l]), q(bl[r]), ans(0);
	if (p == q){
		push_down(p);
		for (int i(l); i<=r; ++i) ans = (ans + a[i]) % mod;
		return ans;
	}
	
	push_down(p);
	for (int i(l); i<=R[p]; ++i) ans = (ans + a[i]) % mod;
	for (int i(p+1); i<q; ++i) ans = (ans + sum[i]) % mod;
	push_down(q);
	for (int i(L[q]); i<=r; ++i) ans = (ans + a[i]) % mod;
	return ans;
}

signed main(){
    n = uread();
    m = uread();
    mod = uread();
	for (int i(1); i<=n; ++i) a[i] = uread();
	init();
	
	while (m--){
	    opt = uread();
	    l = uread();
	    r = uread();
		if (opt == 2){
		    k = uread();
			upd1(l, r, k);
		}else if (opt == 1){
		    k = uread();
			upd2(l, r, k);
		}else printf("%lld\n", query(l, r));
	}
	
	return 0;
}
2023/8/15 19:37
加载中...