树状数组专题
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组专题相关的知识,希望对你有一定的参考价值。
接下里复习专题:数据结构、图论、数学(大致过一遍经典题型)
出了跟队友vp,剩下时间自己找icpc进行vp,两天一场加上补题
我不会在这里倒下的,得不到想要的绝不轻易松手
P3608 [USACO17JAN]Balanced Photo G
板子题:两次建树,分别同统计出左端小于等于a[i]-1的数目,再用总的数目i减去自身和小于a[i]的数目;同理右端也一样。
#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
using namespace std;
const int N =2e6+5;
const int inf=1e18;
const int mod=998244353;
int n,a[N],b[N],tr[N],pl[N],pr[N];
int lowbit(int x)
return x&(-x);
void add(int u,int val)
for(;u<=n;u+=lowbit(u)) tr[u]+=val;
int ask(int u)
int res=0;
for(;u;u-=lowbit(u))
res+=tr[u];
return res;
void solve()
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];
sort(b+1,b+n+1);
int len=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+n+1,a[i])-b;
// for(int i=1;i<=n;i++)
// cout<<a[i]<<" ";
// cout<<endl;
for(int i=1;i<=n;i++)
pl[i]=i-1-ask(a[i]-1);
add(a[i],1);
memset(tr,0,sizeof tr);
for(int i=n;i>=1;i--)
pr[i]=n-i+1-1-ask(a[i]-1);
add(a[i],1);
// for(int i=1;i<=n;i++) cout<<pr[i]<<" ";
// cout<<endl;
int ans=0;
for(int i=1;i<=n;i++)
if(max(pl[i],pr[i])>2*min(pl[i],pr[i])) ans++;
cout<<ans<<endl;
signed main()
//ios;
//int T;cin>>T;
//while(T--)
solve();
return 0;
P3801 红色的幻想乡
单点修改+区间查询+简单容斥
#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
using namespace std;
const int N =2e6+5;
const int inf=1e18;
const int mod=998244353;
int n,m,q,a[N],b[N],tr[N],tr2[N],mx[N],my[N];
int lowbit(int x)
return x&(-x);
void add(int tr[],int u,int val)
for(;u<N;u+=lowbit(u)) tr[u]+=val;
int ask(int tr[],int u)
int res=0;
for(;u;u-=lowbit(u)) res+=tr[u];
return res;
void solve()
cin>>n>>m>>q;
while(q--)
int op;cin>>op;
if(op==1)
int x,y;cin>>x>>y;
if(mx[x]==0) mx[x]=1,add(tr,x,1);
else mx[x]=0,add(tr,x,-1);
if(my[y]==0) my[y]=1,add(tr2,y,1);
else my[y]=0,add(tr2,y,-1);
else
int sx,sy,dx,dy;cin>>sx>>sy>>dx>>dy;
int p=ask(tr,dx)-ask(tr,sx-1);
int q=ask(tr2,dy)-ask(tr2,sy-1);
int ans=p*(dy-sy+1)+q*(dx-sx+1)-2*p*q;
cout<<ans<<endl;
signed main()
//ios;
//int T;cin>>T;
//while(T--)
solve();
return 0;
P4231 三步必杀
数学推导+二级差分
#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
using namespace std;
const int N =2e7+5;
const int inf=1e18;
const int mod=998244353;
int n,m,q,a[N],b[N],c[N],tr[N],tr2[N];
int lowbit(int x)
return x&(-x);
void add(int tr[],int u,int val)
for(;u<N;u+=lowbit(u)) tr[u]+=val;
int ask(int tr[],int u)
int res=0;
for(;u;u-=lowbit(u)) res+=tr[u];
return res;
void solve()
cin>>n>>m;
for(int i=1;i<=m;i++)
int l,r,s,e;cin>>l>>r>>s>>e;
int d=(e-s)/(r-l);
a[l]=a[l]+s;
a[l+1]=a[l+1]+d-s;
a[r+1]=a[r+1]-e-d;
a[r+2]=a[r+2]+e;
int mx=0,ans=0;
for(int i=1;i<=n;i++)
b[i]=b[i-1]+a[i];
c[i]=c[i-1]+b[i];
if(c[i]>mx) mx=c[i];
ans^=c[i];
cout<<ans<<" "<<mx<<endl;
signed main()
ios;
//int T;cin>>T;
//while(T--)
solve();
return 0;
P4392 [BOI2007]Sound 静音问题
ST表做法在空间上卡了我一个点MLE了 ,还是得用树状数组写。还是卡过去了,忘记关long long了,好蠢。
#include <bits/stdc++.h>
#define endl '\\n'
//#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
using namespace std;
const int N =1e6+5;
const int inf=1e18;
const int mod=998244353;
int n,m,c;
bool flag;
int st[1000005][12],st2[1000005][12];
inline int sch(int l,int r)
int p=log2(r-l+1);
return max(st[l][p],st[r-(1<<p)+1][p]);
inline int sch2(int l,int r)
int p=log2(r-l+1);
return min(st2[l][p],st2[r-(1<<p)+1][p]);
void solve()
cin>>n>>m>>c;
for(int i=1; i<=n; i++)
int x;
cin>>x;
st[i][0]=st2[i][0]=x;
for(int j=1; (1<<j)<=m; j++)
for(int i=1; i-1+(1<<j)<=n; i++)
st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
st2[i][j]=min(st2[i][j-1],st2[i+(1<<j-1)][j-1]);
for(int i=1; i<=n-m+1; i++)
int r=sch(i,i+m-1),l=sch2(i,i+m-1);
if(r-l<=c)
flag=1;
cout<<i<<endl;
if(flag==0) cout<<"NONE"<<endl;
signed main()
//ios;
//int T;cin>>T;
//while(T--)
solve();
return 0;
以上是关于树状数组专题的主要内容,如果未能解决你的问题,请参考以下文章
Mobile phones(二维树状数组) POJ - 1195
火柴排队(NOIP2013)(附树状数组专题讲解(其实只是粗略。。。))