树状数组黑科技
标题党。。
也许常数会比较小吧。。。
普通平衡树
其实这个东西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;
}