分块,对拍拍了一下午WA60pts,求调
查看原帖
分块,对拍拍了一下午WA60pts,求调
773659
Elysia11115480楼主2024/7/19 16:19
#include<bits/stdc++.h>
//luoguP2357
#define int long long
using namespace std;
typedef long long ll;

int n, p, op, l, r;
int len, m;//块长,块个数 
ll k;
ll a[200005];
struct blocks{
	int l, r;
	ll sum;//不包括ch 
	ll ch;//修改
	int len;
	int Cls(int stai, int qlen)
	{
		if (stai + qlen - 1 > n)
			len = n - stai + 1;
		else
			len = qlen;
		l = stai, r = stai + len - 1;
		for (int i = l;i <= r; ++i)
			sum += a[i];
		ch = 0;
		return r + 1;
	}
	int Sum()
	{
		return sum + ch * (r - l + 1); 
	}
	void change(ll k)
	{
		ch += k;
	}
	void changePoint(int p, int k)
	{
		a[p] += k;
		sum += k;
	}
	ll Get(int p)
	{
		return a[p] + ch;
	}
	ll GetSum()
	{
		return sum + ch * (r - l + 1);
	}
}blck[2005];
signed main()
{
	//freopen("a.in", "r", stdin);
	//freopen("my.out", "w", stdout);
	scanf("%d%d", &n, &p);
	for (int i = 1;i <= n; ++i)
		scanf("%lld", a + i);
	len = (int)sqrt(n);
	for (int i = 1, j = 1;i <= n; i = blck[j].Cls(i, len), ++j) m = j;
	blck[0].r = 0;
	blck[m + 1].l = n + 1; 
	for (int t = 1;t <= p; ++t)
	{
		scanf("%d", &op);
		//printf("操作#%d\n", t);
		if(op == 1)
		{
			scanf("%d%d%lld", &l, &r, &k);
			//printf("add %d,%d\n", l, r);
			int le, li, re, ri;
			for (int i = 1; i <= m + 1; ++i){
				if (l < blck[i].l)
				{
					le = blck[i].l;
					li = i - 1;
					break;
				}
				if (l == blck[i].l)
				{
					le = blck[i].l;
					li = i;
					break;
				}
			}
			for (int i = 1; i <= m; ++i){
				if (r < blck[i].r)
				{
					re = blck[i].l;
					ri = i;
					break;
				}
				if (r == blck[i].r)
				{
					re = blck[i].r;
					ri = i;
					break;
				}			
			}
			//printf("li=%d,ri=%d\n", li, ri);
			if (li == ri)
			{
				for (int i = l;i <= r; ++i)
					blck[ri].changePoint(i, k);
				
				//for (int i = 1;i <= m; ++i)
				//	for (int j = blck[i].l;j <= blck[i].r; ++j)
				//		printf("%lld\n", blck[i].Get(j));
				continue;
			}
			if (l != le){
				for (int i = l;i <= le - 1; ++i)
					blck[li].changePoint(i, k);
				//printf("左区间非整块区域:%d,%d\n", l, le);
				++li;
			}	
			if (r != blck[ri].r){
				for (int i = re;i <= r; ++i)
					blck[ri].changePoint(i, k);
				//printf("右区间非整块区域:%d,%d\n", re, r); 
				--ri;					
			}
			//printf("区间from %d to %d\n", li, ri);
			for (int i = li;i <= ri; ++i)
				blck[i].change(k)/*, printf("整块区域:块%d\n", i)*/;
		//	for (int i = 1;i <= m; ++i)
			//	for (int j = blck[i].l;j <= blck[i].r; ++j)
			//		printf("%lld\n", blck[i].Get(j));
		}
		else if (op == 2){
			scanf("%lld", &k);
			blck[1].changePoint(1, k);			
			//for (int i = 1;i <= m; ++i)
			//	for (int j = blck[i].l;j <= blck[i].r; ++j)
			//		printf("%lld\n", blck[i].Get(j));
		}
		else if (op == 3){
			scanf("%lld", &k);
			blck[1].changePoint(1, -k);
			//for (int i = 1;i <= m; ++i)
			//	for (int j = blck[i].l;j <= blck[i].r; ++j)
			//		printf("%lld\n", blck[i].Get(j));
		}
		else if (op == 4){
			ll res = 0;
			scanf("%d%d", &l, &r);
			int le, li, re, ri;
			for (int i = 1; i <= m + 1; ++i)
			{
				if (l < blck[i].l)
				{
					le = blck[i].l;
					li = i;
					break;
				}
				if (l == blck[i].l)
				{
					le = blck[i].l;
					li = i;
					break;
				}
			}
			for (int i = 1; i <= m; ++i)
			{
				if (r < blck[i].r)
				{
					re = blck[i].l;
					ri = i - 1;
					break;
				}
				if (r == blck[i].r)
				{
					re = blck[i].r;
					ri = i;
					break;
				}
			}
			if (li == ri)
			{
				for (int i = l;i <= r; ++i)
					res += blck[ri].Get(i);
				printf("%lld\n", res);
				continue;
			}
			if (l != le){
				//printf("%d-%d\n", l, le);
				for (int i = l;i <= le - 1; ++i)
					res += blck[li].Get(i);
				printf("左区间非整块区域:%d,%d\n", l, le - 1);
				//++li;
			}	
			
			if (r != re){
				for (int i = re;i <= r; ++i)
					res += blck[ri].Get(i);
				printf("右区间非整块区域:%d,%d\n", re, r); 
				--ri;					
			}
			printf("区间from %d to %d\n", li, ri);
			for (int i = li;i <= ri; ++i)
				res += blck[i].GetSum()/*, printf("整块区域:块%d +=%lld\n", i, blck[i].GetSum())*/;
			//for (int i = 1;i <= m; ++i)
			//	for (int j = blck[i].l;j <= blck[i].r; ++j)
			//		printf("%lld\n", blck[i].Get(j));
			printf("%lld\n", res);
		}
		else
		{
			printf("%lld\n", blck[1].Get(1));
		}
	}
    return 0;
}

蒟蒻调了一下午,60ptsWA,求调 QwQ

2024/7/19 16:19
加载中...