#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#define PI atan(1.0)*4
#define e 2.718281828
#define rp(i,s,t) for (i = (s); i <= (t); i++)
#define RP(i,s,t) for (i = (t); i >= (s); i--)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define push_back() pb()
#define pair<int,int> pii;
#define fastIn \
ios_base::sync_with_stdio(0); \
cin.tie(0);
using namespace std;
inline int read()
{
int a=0,b=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
b=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
a=(a<<3)+(a<<1)+c-'0';
c=getchar();
}
return a*b;
}
inline void write(int n)
{
if(n<0)
{
putchar('-');
n=-n;
}
if(n>=10)
write(n/10);
putchar(n%10+'0');
}
const int N=1e5+7;
int a[N],c[N];
char s[10];
int n;
int lowbit(int x){
return x&(-x);
}
int query(int x){
int sum=0;
while(x>0){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update(int index,int x){
while(index<=n){
c[index]+=x;
index+=lowbit(index);
}
}
int main(){
int T=read(),i,Case=0;
while(T--){
n=read();
mst(a,0);
mst(c,0);
rp(i,1,n){
a[i]=read();
update(i,a[i]);
}
printf("Case %d:\n",++Case);
while(~scanf("%s",s)){
if(s[0]=='Q'){
int l=read(),r=read();
write(query(r)-query(l-1));
printf("\n");
}
else if(s[0]=='A'){
int x=read(),delta=read();
update(x,delta);
}
else if(s[0]=='S'){
int x=read(),delta=read();
update(x,-delta);
}
else if(s[0]=='E') break;
}
}
return 0;
}
C國的死對頭A國這段時間正在進行軍事演習,是以C國間諜頭子Derek和他手下Tidy又開始忙乎了。A國在海岸線沿直線布置了N個工兵營地,Derek和Tidy的任務就是要監視這些工兵營地的活動情況。由于采取了某種先進的監測手段,是以每個工兵營地的人數C國都掌握的一清二楚,每個工兵營地的人數都有可能發生變動,可能增加或減少若幹人手,但這些都逃不過C國的監視。
中央情報局要研究敵人究竟演習什麼戰術,是以Tidy要随時向Derek彙報某一段連續的工兵營地一共有多少人,例如Derek問:“Tidy,馬上彙報第3個營地到第10個營地共有多少人!”Tidy就要馬上開始計算這一段的總人數并彙報。但敵兵營地的人數經常變動,而Derek每次詢問的段都不一樣,是以Tidy不得不每次都一個一個營地的去數,很快就精疲力盡了,Derek對Tidy的計算速度越來越不滿:"你個死肥仔,算得這麼慢,我炒你鱿魚!”Tidy想:“你自己來算算看,這可真是一項累人的工作!我恨不得你炒我鱿魚呢!”無奈之下,Tidy隻好打電話向計算機專家Windbreaker求救,Windbreaker說:“死肥仔,叫你平時做多點acm題和看多點算法書,現在嘗到苦果了吧!”Tidy說:"我知錯了。。。"但Windbreaker已經挂掉電話了。Tidy很苦惱,這麼算他真的會崩潰的,聰明的讀者,你能寫個程式幫他完成這項工作嗎?不過如果你的程式效率不夠高的話,Tidy還是會受到Derek的責罵的.
Input
第一行一個整數T,表示有T組資料。
每組資料第一行一個正整數N(N<=50000),表示敵人有N個工兵營地,接下來有N個正整數,第i個正整數ai代表第i個工兵營地裡開始時有ai個人(1<=ai<=50)。
接下來每行有一條指令,指令有4種形式:
(1) Add i j,i和j為正整數,表示第i個營地增加j個人(j不超過30)
(2)Sub i j ,i和j為正整數,表示第i個營地減少j個人(j不超過30);
(3)Query i j ,i和j為正整數,i<=j,表示詢問第i到第j個營地的總人數;
(4)End 表示結束,這條指令在每組資料最後出現;
每組資料最多有40000條指令
Output
對第i組資料,首先輸出“Case i:”和回車,
對于每個Query詢問,輸出一個整數并回車,表示詢問的段中的總人數,這個數保持在int以内。
Sample Input
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>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
//這裡的預處理使得代碼更加簡潔
const int maxn = 5e4+3;
using namespace std;
int sum[maxn*4];
int a,b;
void push_up(int rt)//向上傳遞,把目前結點的資訊更新給父節點
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&sum[rt]);
return ;
}
int m = (l+r)/2;
build(lson);
build(rson);
push_up(rt);
}
int query(int L,int R,int l,int r,int rt)//區間求和
{
if(L<=l&&r<=R)
return sum[rt];
int m = (l+r)/2;
int ans=0;
if(L<=m) ans+=query(L,R,lson);
if(m<R) ans+=query(L,R,rson);
return ans;
}
void sub(int l,int r,int rt)//單點更新——減少
{
if(l==r)
{
sum[rt]-=b;
return ;
}
int m = (l+r)/2;
if(a<=m) sub(lson);
else sub(rson);
push_up(rt);
}
void add(int l,int r,int rt)//單點更新——增加
{
if(l==r)
{
sum[rt]+=b;
return ;
}
int m = (l+r)/2;
if(a<=m) add(lson);
else add(rson);
push_up(rt);
}
int main(int argc, char** argv) {
int T;
scanf("%d",&T);
for(int cas = 1;cas<=T;cas++)
{
printf("Case %d:\n",cas);
int n;
scanf("%d",&n);
build(1,n,1);
char str[10];
while(scanf("%s",str))
{
if(str[0]=='E') break;
scanf("%d %d",&a,&b);
if(str[0]=='Q')
printf("%d\n",query(a,b,1,n,1));
else if(str[0]=='S')
sub(1,n,1);
else
add(1,n,1);
}
}
return 0;
}
下面給出樹狀數組的做法
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#define PI atan(1.0)*4
#define e 2.718281828
#define rp(i,s,t) for (i = (s); i <= (t); i++)
#define RP(i,s,t) for (i = (t); i >= (s); i--)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define push_back() pb()
#define pair<int,int> pii;
#define fastIn \
ios_base::sync_with_stdio(0); \
cin.tie(0);
using namespace std;
inline int read()
{
int a=0,b=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
b=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
a=(a<<3)+(a<<1)+c-'0';
c=getchar();
}
return a*b;
}
inline void write(int n)
{
if(n<0)
{
putchar('-');
n=-n;
}
if(n>=10)
write(n/10);
putchar(n%10+'0');
}
const int N=1e5+7;
int a[N],c[N];
char s[10];
int n;
int lowbit(int x){
return x&(-x);
}
int query(int x){
int sum=0;
while(x>0){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update(int index,int x){
while(index<=n){
c[index]+=x;
index+=lowbit(index);
}
}
int main(){
int T=read(),i,Case=0;
while(T--){
n=read();
mst(a,0);
mst(c,0);
rp(i,1,n){
a[i]=read();
update(i,a[i]);
}
printf("Case %d:\n",++Case);
while(~scanf("%s",s)){
if(s[0]=='Q'){
int l=read(),r=read();
write(query(r)-query(l-1));
printf("\n");
}
else if(s[0]=='A'){
int x=read(),delta=read();
update(x,delta);
}
else if(s[0]=='S'){
int x=read(),delta=read();
update(x,-delta);
}
else if(s[0]=='E') break;
}
}
return 0;
}