树状数组,不知道哪里错了,全wa
  • 板块P2357 守墓人
  • 楼主Exile_Code
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/23 13:06
  • 上次更新2023/11/23 17:31:05
查看原帖
树状数组,不知道哪里错了,全wa
819682
Exile_Code楼主2023/11/23 13:06
#define  _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <algorithm>
#include <list>
#include <string>
#include <cmath>
#include <bitset>
#include <stack>
#include <unordered_set>


#define ull				unsigned long long 
#define ll				long long
#define pii				pair<ll ,ll>
#define ft				first
#define sd				second
#define pr				pair
#define cy				cout<<"Yes"<<endl
#define cn				cout<<"No"<<endl
#define forn(i,n)		for(int (i)=0;(i)<(n);(i)++)   
#define forne(i,n)		for(int (i)=1;(i)<=(n);(i)++)
#define rforn(i,n)		for(int (i)=(n-1);(i)>=(0);(i)--)   
#define rforne(i,n)		for(int (i)=(n);(i)>=(1);(i)--)
#define sorta(a)		sort((a).begin(),(a).end())
#define sortcmp(a,cmp)	sort((a).begin(),(a).end(),cmp)
#define vv				vector


const int inf = 0x4f4f4f4f;
const int N = 2e5 + 5;
ll t;


//树状数组
class Tree_Array {
private:
	/*
		前驱:c[i]左侧的所有字数的根	直接前驱:c[i-lowbit(i)],即c[i]左侧紧邻的子树的根
		后继:c[i]的所有祖先			直接后继:c[i+lowbit(i)],继c[i]的父节点
	*/

	//可以用差分树状数组来表示一个数组,其中前缀和n为第n个数
	int n, a[N];//原数组
	ll sm[N];
	ll c1[N];//树状数组
	int lowbit(int x) {
		return x & (-x);//找寻二进制最低的那个位
	}
	//S=SSc1,可以观察到c1出现了n次,c2出现了n-1次,即ci出现了n-i+1次
	//S=S(x-i+1)*ci=S(x+1)*ci-Si*ci
	ll c2[N];//储存(i-1)*c[i]
public:
	void init(int n) {
		this->n = n;
		memset(a, 0, sizeof(a));
		memset(c1, 0, sizeof(c1));
		memset(c2, 0, sizeof(c2));
		memset(sm, 0, sizeof(sm));
		forne(i,n){
			cin >> a[i];
		}
		forne(i, n) {
			add(c1, i, a[i] - a[i - 1]);
			add(c2, i, i * (a[i] - a[i - 1]));
		}
	}
	void add(ll c[], int i, ll ret) {//点修改
		for (; i <= n; i += lowbit(i))
			c[i] += ret;
	}
	ll sum(ll c[], int i) {//前缀和
		ll s = 0;
		for (; i > 0; i -= lowbit(i))
			s += c[i];
		return s;
	}
	void add_SSd( int l, int r, ll ret) {//区间修改
		add(c1, l, ret);		add(c1, r + 1, -ret);
		add(c2, l, l * ret);	add(c2, r + 1, -(r+1) * ret);
	}
	ll sum_ssd(int l, int r) {//区间查询 (l,l)退化成点查询
		return	sm[r]-sm[l-1]+ 
				(r + 1) * sum(c1, r) - (l)*sum(c2, l - 1)
				- (sum(c2, r) - sum(c2, l - 1));
	}
};

void solve() {
	
	int n, f; cin >> n >> f;
	
	Tree_Array s;
	s.init(n);
	forn(i, f) {
		int a; cin >> a;
		switch (a)
		{
		case 1:
			int l, r; cin >> l >> r;
			int ret; cin >> ret;
			s.add_SSd(l, r, ret);
			break;
		case 2:
			cin >> ret;
			s.add_SSd(1, 1, ret);
			break;
		case 3:
			cin >> ret;
			s.add_SSd(1, 1, -ret);
			break;
		case 4:
			cin >> l >> r;
			cout << s.sum_ssd(l, r) << endl;
			break;
		case 5:
			cout << s.sum_ssd(1, 1) << endl;
			break;
		default:
			break;
		}
	}




}
int main() {

	//cin >> t;
	t = 1;
	while (t--)
		solve();

	return 0;
}




2023/11/23 13:06
加载中...