标签:nbsp 接下来 mozilla weather inpu while center ali namespace
自用模板,树状数组
原理不讲,只说用法
树状数组建立成功之后,传入参数i,j 能轻松求解出来 数组a[i]+a[..]+...+a[j]的值
核心函数lowbit(),无论是建立树状数组还是更新,这个函数就最重要的函数,也是降低时间复杂度的精髓所在。
int lowbit(int x)
{
return x&(-x);
}
树状数组的建立,实际上是不断更新的过程,想让某个元素增加或者减少,传入参数下标和想要修改的值,就可以进行更新操作
有时候,我们想直接把某个位置的值更新为X,传入参数的时候可以这样传值 change(int index,(X-a[index])){} 就可以实现想要的效果了。
void change(int index,int value)
{
while(index<=n)
{
T[index]+=value;
index+=lowbit(index);
}
}
前面所有的操作都是为了最后的查询进行铺垫,这个函数计算的是从 a[0] +....+a[x] 的值
int sum(int x)
{
int ans = 0;
while(x>0)
{
ans+=T[x];
x-=lowbit(x);
}
return ans;
}
如果想要计算一段区间的值,假设想计算从a[L] +....+a[R]的值,我么根据Sum函数进行一些修改就可以实现这个功能,实际上就是Sum(R) - Sum(L-1)
1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End
Sample Output
Case 1:
6
33
59
#include<bits/stdc++.h>
using namespace std;
const int maxn = 50010;
int T[maxn*2],n;
int lowbit(int x)
{
return x&(-x);
}
void change(int index,int value)
{
while(index<=n)
{
T[index]+=value;
index+=lowbit(index);
}
}
int sum(int x)
{
int ans = 0;
while(x>0)
{
ans+=T[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
int cases;
scanf("%d",&cases);
for(int k=1;k<=cases;k++)
{
memset(T,0,sizeof(T));
scanf("%d",&n);
int t;
for(int i=1;i<=n;i++)
{
scanf("%d",&t);
change(i,t);
}
printf("Case %d:\n",k);
string s;
while(cin>>s)
{
int L,R;
if(s=="End") break;
scanf("%d%d",&L,&R);
if(s=="Query")
{
printf("%d\n",sum(R)-sum(L-1));
}
else if(s=="Add")
{
change(L,R);
}
else if(s=="Sub")
{
change(L,-R);
}
}
}
}
标签:nbsp 接下来 mozilla weather inpu while center ali namespace
原文地址:https://www.cnblogs.com/masterchd/p/8886561.html