树状数组黑科技

标题党。。

也许常数会比较小吧。。。

普通平衡树

其实这个东西01Trie也是可以实现的

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=2e7+10,Lg=log2(N);
int n,opt,x,base;
struct BIT
{
	int lim,tre[N];
	#define lowbit(x) (x&(-x))
	inline void insert(int x,int val){for(int i=x;i<=lim;i+=lowbit(i))tre[i]+=val;}
	inline int query(int x){int sum=0;for(int i=x;i;i-=lowbit(i))sum+=tre[i];return sum;}
	inline int kth(int rk)
	{
		int temp=0,cnt=0;
		for(int i=Lg;~i;i--)
		{
			temp+=(1ll<<i);
			if(temp>lim||cnt+tre[temp]>=rk) temp-=(1ll<<i);
			else cnt+=tre[temp];
		}
		return temp+1;
	}
}T;
#undef int
int main()
{
	#define int long long
	n=read(); T.lim=N-9; base=1e7+1;
	while(n--)
	{
		opt=read(); x=read();
		if(opt==1) T.insert(x+base,1);
		else if(opt==2) T.insert(x+base,-1);
		else if(opt==3) printf("%lld\n",T.query(x+base-1)+1);
		else if(opt==4) printf("%lld\n",T.kth(x)-base);
		else if(opt==5) printf("%lld\n",T.kth(T.query(x+base-1))-base);
		else printf("%lld\n",T.kth(T.query(x+base)+1)-base);
	}
	return 0;
}

一维区间加值区间求和

其实就是对于差分数组以及区间查询进行了一些公式推导,然后维护一个常数项一个一次项。

#include <bits/stdc++.h>
#define int long long 
#define ull unsigned long long
#define f() cout<<"Failed"
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=1e5+10;
int n,m;
struct BIT
{
	int tre[N];
	inline int lowbit(register int x){return x&(-x);}
	inline void insert(register int x,int val){for(register int i=x;i<=n;i+=lowbit(i))tre[i]+=val;}
	inline int query(register int x){register int temp=0;for(register int i=x;i;i-=lowbit(i))temp+=tre[i];return temp;}
};
struct IN_BIT
{
	BIT t0,t1;
	inline void insert(register int l,register int r,register int val)
	{
		t0.insert(l,val); t0.insert(r+1,-val);
		t1.insert(l,(l-1)*val); t1.insert(r+1,-val*r);
	}
	inline int query(register int l,register int r)
	{
		return r*t0.query(r)-(l-1)*t0.query(l-1)-(t1.query(r)-t1.query(l-1));
	}
}T;
void solve()
{
	register int opt,x,y,k; opt=read(); x=read(); y=read();
	if(opt==1) k=read(),T.insert(x,y,k);
	else printf("%lld\n",T.query(x,y));
}
signed main()
{
	n=read(); m=read();
	for(register int i=1,x;i<=n;i++) x=read(),T.insert(i,i,x);
	while(m--) solve();
	return 0;
}

二维区间加值区间求和

也是对于差分数组维护,维护常数项,两个一次项,二次项

#include<bits/stdc++.h>
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=2100;
int n,m; char ch[10];
struct BIT
{
	int tre[N][N];
	#define lowbit(x) (x&(-x))
	inline void insert(register int x,register int y,register int val)
	{
		for(register int i=x;i<=n;i+=lowbit(i))
			for(register int j=y;j<=m;j+=lowbit(j))
				tre[i][j]+=val;
	}
	inline int query(register int x,register int y)
	{
		register int sum=0;
		for(register int i=x;i;i-=lowbit(i))
			for(register int j=y;j;j-=lowbit(j))
				sum+=tre[i][j];
		return sum;
	}
};
struct IN_BIT
{
	BIT T0,Tx,Ty,Txy;
	inline void insert(register int x,register int y,register int val)
	{T0.insert(x,y,val); Tx.insert(x,y,val*x); Ty.insert(x,y,val*y); Txy.insert(x,y,val*x*y);}
	inline int query(register int x,register int y)
	{return T0.query(x,y)*(x*y+x+y+1)-Tx.query(x,y)*(y+1)-Ty.query(x,y)*(x+1)+Txy.query(x,y);}
	inline void insert(register int x,register int y,register int x2,register int y2,register int val)
	{insert(x,y,val); insert(x2+1,y2+1,val); insert(x,y2+1,-val); insert(x2+1,y,-val);}
	inline int query(register int x,register int y,register int x2,register int y2)
	{return query(x2,y2)+query(x-1,y-1)-query(x-1,y2)-query(x2,y-1);}
}T;
int main()
{
	n=read(); m=read();
	while(scanf("%s",ch+1)!=-1)
	{
		int x,y,x2,y2,val; x=read(); y=read(); x2=read(); y2=read();
		if(ch[1]=='L') val=read(),T.insert(x,y,x2,y2,val);
		else printf("%d\n",T.query(x,y,x2,y2));
	}
	return 0;
}
posted @ 2021-11-15 21:35  Varuxn  阅读(89)  评论(0编辑  收藏  举报