【code[vs]】1082 線段樹練習 3 樹狀數組區間修改、區間查詢

評測ID: 3180536
用戶名: FMM
狀態: 測試通過 Accepted 
得分 : 100 
總時間耗費: 550ms 
總內存耗費: 4 MB

測試點#ask1.in 結果: 內存使用量: 256kB 時間使用量: 1ms 

測試點#ask10.in 結果: 內存使用量: 4328kB 時間使用量: 174ms 
測試點#ask2.in 結果: 內存使用量: 128kB 時間使用量: 1ms 
測試點#ask3.in 結果: 內存使用量: 1896kB 時間使用量: 21ms 
測試點#ask4.in 結果: 內存使用量: 2156kB 時間使用量: 79ms 
測試點#ask5.in 結果: 內存使用量: 2156kB 時間使用量: 78ms 
測試點#ask6.in 結果: 內存使用量: 4332kB 時間使用量: 174ms 
測試點#ask7.in 結果: 內存使用量: 128kB 時間使用量: 2ms 
測試點#ask8.in 結果: 內存使用量: 128kB 時間使用量: 1ms 

測試點#ask9.in 結果: 內存使用量: 1772kB 時間使用量: 19ms 

用兩個樹狀數組維護兩個數值之間的差時間區間修改與區間查詢

#include <cstdio>
using namespace std;

long long tr[200005],tr_[200005];
int m,n,q,w,e,k,lst;

inline int lowbit(int x){return x&-x;}

void add(int q,int d)
{
	int x=q;
	while (x<=n)
	{
		tr[x]+=d;
		tr_[x]+=d*q;
		x+=lowbit(x);
	}
	return;
}

long long query(int q)
{
	long long ans=0,x=q;
	while (x>0)
	{
		ans+=(q+1)*tr[x]-tr_[x];
		x-=lowbit(x);
	}
	return ans;
}

int main(void)
{
	scanf("%d",&n);
	for (register int i=1;i<=n;++i)
	{
		scanf("%d",&q);
		add(i,q-lst);
		lst=q;
	}
	scanf("%d",&m);
	for (register int i=1;i<=m;++i)
	{
		scanf("%d",&k);
		if (k==1)
		{
			scanf("%d%d%d",&q,&w,&e);
			add(q,e),add(w+1,-e);
		}
		else
		if (k==2)
		{
			scanf("%d%d",&q,&w);
			printf("%lld\n",query(w)-query(q-1));
		}
	}
	return 0;
}
/******************************************************/

2017.10.11

新的做法

似乎並不需要差值

但同樣要用到兩個樹狀數組

似乎可以快一點

評測ID: 3190661
用戶名: FMM
狀態: 測試通過 Accepted 
得分 : 100 
總時間耗費: 312ms 
總內存耗費: 5 MB

測試點#ask1.in 結果: 內存使用量: 256kB 時間使用量: 0ms 
測試點#ask10.in 結果: 內存使用量: 5992kB 時間使用量: 109ms 
測試點#ask2.in 結果: 內存使用量: 256kB 時間使用量: 0ms 
測試點#ask3.in 結果: 內存使用量: 2540kB 時間使用量: 9ms 
測試點#ask4.in 結果: 內存使用量: 3052kB 時間使用量: 41ms 
測試點#ask5.in 結果: 內存使用量: 3052kB 時間使用量: 42ms 
測試點#ask6.in 結果: 內存使用量: 5868kB 時間使用量: 102ms 
測試點#ask7.in 結果: 內存使用量: 256kB 時間使用量: 1ms 
測試點#ask8.in 結果: 內存使用量: 256kB 時間使用量: 1ms 
測試點#ask9.in 結果: 內存使用量: 2668kB 時間使用量: 7ms 

#include <cstdio>
#define C (c=getchar())
#define lowbit(x) (x&-x)
using namespace std;

long long m,n,a[200005],opt,tr[200005],tr_[200005];

inline void read(long long &n)
{
	long long f=1;char c;n=0;C;
	while (c<'0'||c>'9') c=='-'?f=-1,C:C;
	while (c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,C;
	return (void)(n*=f);
}

void add(long long q,long long x)
{
	long long p=q,w=q*x;
	while (p<=n)
	{
		tr[p]+=x;
		tr_[p]+=w;
		p+=lowbit(p);
	}
	return;
}

long long query(long long x)
{
	long long p=x,sum=0,sum_=0;
	while (p>0)
	{
		sum+=tr[p];
		sum_+=tr_[p];
		p-=lowbit(p);
	}
	return (x+1)*sum-sum_;
}

int main(void)
{
	long long q,w,e;
	read(n);
	for (register long long i=1;i<=n;++i) read(a[i]),a[i]+=a[i-1];
	read(m);
	for (register long long i=1;i<=m;++i)
	{
		read(opt);
		if (opt==1)
		{
			read(q),read(w),read(e);
			add(q,e),add(w+1,-e);
		}
		else
		{
			read(q),read(w);
			printf("%lld\n",a[w]+query(w)-a[q-1]-query(q-1));
		}
	}
	return 0;
}


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