【CodeVS】1080 線段樹練習 分塊 線段樹 樹狀數組 開放性

【代碼1】塊狀數組
#include <bits/stdc++.h>
using namespace std;

typedef long long Lint;
const int N=100010;
const int BLOCK_SIZE=400;
const int BLOCK_NUMBER=400;

int n,w[N],unit,m;
struct Block
{
	Lint w[BLOCK_NUMBER];
	Lint sum;
}ud_list[BLOCK_SIZE];

inline int Read(void)
{
	int s=0,f=1; char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
	for (;isdigit(c);c=getchar()) s=s*10+c-'0';
	return s*f;
}

void Update(int pos,int add)
{
	int goalBlock=(pos-1)/unit+1;
	pos=pos-(goalBlock-1)*unit;
	ud_list[goalBlock].w[pos]+=add;
	ud_list[goalBlock].sum+=add;
}

Lint Query(int l,int r)
{
	int leftBlock=(l-1)/unit+1,rightBlock=(r-1)/unit+1; Lint sum=0;
	if (leftBlock==rightBlock)
		for (int i=l-(leftBlock-1)*unit;i<=r-(rightBlock-1)*unit;i++) sum+=ud_list[leftBlock].w[i];
	else
	{
		for (int i=leftBlock+1;i<=rightBlock-1;i++) sum+=ud_list[i].sum;
		for (int i=l-(leftBlock-1)*unit;i<=unit;i++) sum+=ud_list[leftBlock].w[i];
		for (int i=1;i<=r-(rightBlock-1)*unit;i++) sum+=ud_list[rightBlock].w[i];
	}
	return sum;
}

int main(void)
{
	n=Read();
	for (int i=1;i<=n;i++) w[i]=Read();
	
	int nowBlock=0,nowLoc=0;
	unit=(int)sqrt(n);
	for (int i=1;i<=n;i++)
	{
		if ((i-1)%unit==0) nowBlock++,nowLoc=0;
		ud_list[nowBlock].w[++nowLoc]=w[i];
		ud_list[nowBlock].sum+=w[i];
	}
	
	int k,x,y;
	m=Read();
	for (int i=1;i<=m;i++)
	{
		k=Read(),x=Read(),y=Read();
		if (k==1)
			Update(x,y);
		else printf("%lld\n",Query(x,y));
	}
	
	return 0;
}

發佈了137 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章