首页 > 其他分享 >做题记录整理树状数组(单点修改区间查询)(区间修改单点查询)(区间修改区间查询)(2022/9/16)

做题记录整理树状数组(单点修改区间查询)(区间修改单点查询)(区间修改区间查询)(2022/9/16)

时间:2022-09-18 22:36:09浏览次数:91  
标签:单点 int xg long 查询 read 区间

单点修改区间查询

#include<bits/stdc++.h>
using namespace std;
long long a,tree[10000000*4],n;
long long lb(long long x)
{
	return x&-x;
}
void xg(long long x,long long k)
{
	while(x<=n)
	{
		tree[x]+=k;
		x+=lb(x);
	}
}

long long cx(long long x,long long y)
{
	long long ans=0;x--;
	while(y)
	{
		ans+=tree[y];
		y-=lb(y);
	}
	while(x)
	{
		ans-=tree[x];
		x-=lb(x);
	}
	return ans;
}
int main()
{
    long long a,m,ji,x,y,k;
	cin>>n>>m;
	for(long long i = 1;i<=n;i++)
	cin>>a,xg(i,a);

	for(long long i = 1;i<=m;i++)
	{
		long long ji;
		cin>>ji;
		if(ji==1)
		{
			cin>>x>>k;
			xg(x,k);
		}
		else
		{
			cin>>x>>y;
			cout<<cx(x,y)<<endl;
		}
	}
	return 0;
}

区间修改单点查询

#include<bits/stdc++.h>
using namespace std;
int aa[1000050],tree[1000050],n,m,k,cz,x,y;
int lowbit(int x) 
{
	return x&-x;
}
void build()
{
	for(int i = 1;i <=n;i++)
	{
		for(int j = i-lowbit(i)+1;j <= i;j++)
		tree[i]+=aa[j];
	}
}

void cz1(int a,int b,int c)
{
		while(a<=n)
		{
		tree[a]+=c;
		a+=lowbit(a);
		}
		b+=1;
		while(b<=n)
		{
		tree[b]-=c;
		b+=lowbit(b);
		}
}
void cz2(int a)
{
	int ans = 0;
	while(a>0)
	{
		ans+=tree[a];
		a-=lowbit(a);
	}
	cout<<ans<<endl;
}
int main()
{
	int ji=0;
	scanf("%d%d",&n,&m);
	for(int i = 1;i <=n;i++)
	scanf("%d",&aa[i]);
	for(int i = 1;i <=n;i++)
		ji+=aa[i-1],aa[i] -= ji;
	build();
	for(int i = 1;i<=m;i++) 
	{
		scanf("%d",&cz);
		if(cz==1) 
		{
			scanf("%d%d%d",&x,&y,&k);
			cz1(x,y,k);
		}
		else
		{
			scanf("%d",&x);
			cz2(x);
		}
	}
	return 0;
}

区间修改区间查询(甚至速度比线段树快一倍,空间比线段树小一倍)

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
const int N=1e5+5;
ll n,m;
ll t1[N],t2[N],a[N];


ll lb(ll i){return (-i)&i;}
inline int read()
{
	int s = 0,w = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9'){s = s * 10+ch -'0'; ch = getchar();}
	return s * w;
}
void xg(ll x,ll k)
{
	ll ji=x;
	while(x<=n)
	{
		t1[x]+=k;
		t2[x]+=k*(ji-1);
		x+=lb(x);
	}
}
ll cx(ll x)
{
	ll ans=0,ji=x;
	while(x>0)
	{
		ans+=(ji)*t1[x]-t2[x];
		x-=lb(x);
	}
	return ans;
}
int main() 
{
	ll x,y,k,t;
	cin>>n>>m;
	for1(i,1,n)
		a[i]=read(),
		xg(i,a[i]-a[i-1]);
	for1(i,1,m)
	{
	    cin>>t;
	    if(t==1)
    	{
        	x=read(),y=read(),k=read();
	        xg(x,k);
	        xg(y+1,-k);
	    }
        else
        {
    	    x=read(),y=read();
    	    ll t=cx(y)-cx(x-1);
    	    printf("%lld\n",t);
    	}	
	}	
	return 0;
}

标签:单点,int,xg,long,查询,read,区间
From: https://www.cnblogs.com/yyx525jia/p/16706036.html

相关文章