标签: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