萌新求助,分块做法为什么开大数组之后快这么多
查看原帖
萌新求助,分块做法为什么开大数组之后快这么多
347839
Daniel_7216楼主2022/7/27 11:22

Rt,我的思路就是判断块内的是否都为1,如果不是就暴力修改。

这是我的代码:

#include <cstdio>
#include <iostream>
#include <cmath>
#define int long long
using namespace std;
const int maxn = 1e5 + 1;
int n, m, opt, x, y, num, len, bl, br, tmp;
int L[251], R[251], cnt[251], dwy[251], sum[251], a[maxn], belong[maxn];
void init(){
	len = sqrt(n);
	num = len;
	for (int i = 1; i <= num; i++){
		L[i] = (i - 1) * len + 1;
		R[i] = i * len;
	}
	if (R[num] < n){
		num++;
		L[num] = R[num - 1] + 1;
		R[num] = n;
	}
	for (int i = 1; i <= num; i++){
		for (int j = L[i]; j <= R[i]; j++){
			if (a[j] <= 1) cnt[i]++;
			belong[j] = i;
			sum[i] += a[j];
		}
	}
}
int query1(int l, int r){
	int ans = 0;
	bl = belong[l];
	br = belong[r];
	if (bl == br){
		for (int i = l; i <= r; i++){
			ans += a[i];
		}
		return ans;
	}else{
		for (int i = l; i <= R[bl]; i++){
			ans += a[i];
		}
		for (int i = bl + 1; i <= br - 1; i++){
			ans += sum[i];
		}
		for (int i = L[br]; i <= r; i++){
			ans += a[i];
		}
		return ans;
	}
}
void query0(int l, int r){
	bl = belong[l];
	br = belong[r];
	if (bl == br){
		if (sum[bl] <= R[bl] - L[bl] + 1) return;
		for (int i = l; i <= r; i++){
			if (a[i] > 1){
				tmp = a[i];
				a[i] = sqrt(a[i]);
				sum[bl] -= (tmp - a[i]);
			}
		}
	}else{
	    if (sum[bl] > R[bl] - L[bl] + 1){
    		for (int i = l; i <= R[bl]; i++){
    			if (a[i] > 1){
    				tmp = a[i];
    				a[i] = sqrt(a[i]);
    				sum[bl] -= (tmp - a[i]);
    		 	}
    		}	        
	    }
		for (int i = bl + 1; i <= br - 1; i++){
			if (sum[i] <= R[i] - L[i] + 1) continue;
			for (int j = L[i]; j <= R[i]; j++){
				if (a[j] > 1){
					tmp = a[j];
					a[j] = sqrt(a[j]);
					sum[i] -= (tmp - a[j]);
				}
			}
		}
		if (sum[br] > R[br] - L[br] + 1){
    		for (int i = L[br]; i <= r; i++){
    			if (a[i] > 1){
    				tmp = a[i];
    				a[i] = sqrt(a[i]);
    				sum[br] -= (tmp - a[i]);
    			}
    		}		    
		}
	}
}
signed main(){
	scanf("%lld", &n);
	for (int i = 1; i <= n; i++){
		scanf("%lld", &a[i]);
	}
	init();
	scanf("%lld", &m);
	for (int i = 1; i <= m; i++){
		scanf("%lld%lld%lld", &opt, &x, &y);
		if (x > y) swap(x, y);
		if (opt == 0) query0(x, y);
		else printf("%lld\n", query1(x, y));
	}
	return 0;
}

交上去之后是50分,后面的数据T飞了。然后去讨论区看到一个远古帖说要开大数组,然后我把数组开大了一倍,就过了!而且最慢的点也不到100ms!可是很明显代码里不存在数组越界的情况,为什么开大数组会快这么多?

2022/7/27 11:22
加载中...