題目描述:
標準的線段樹。給出序列操作,分別爲對一段區間增值 和 求某一段區間和。
解題思路:
標準的線段樹建樹,修改和查詢操作。這裏要注意的是,對修改操作爲了避免修改到葉子節點而導致的超時問題,令修改到對應的區間即可,而此時爲了保證該區間下的節點能夠意識到自己的值已經被修改了——通過對該區間打延時標記來實現。
附註:有個坑,就是增量得開到64位long long。
代碼:
#include
#include
#define N 100001
typedef struct{
int left, right;
long long tab;
long long inc;//標記
}CH;
CH segTree[4*N];
int n,q, num[N];
long long sum;
void buildTree(int l, int r, int index){
segTree[index].left = l;
segTree[index].right =
r;
segTree[index].tab = 0;
segTree[index].inc = 0;
if(l!=r){
buildTree(l,(l+r)/2,2*index);
buildTree((l+r)/2+1,r,2*index+1);
}
}
void changeTree(int l, int r, int t, int index){
if(segTree[index].left <= l
&& segTree[index].right >= r){
//printf("更改區域[%d-%d],增加值%d\n",segTree[index].left,segTree[index].right,
(r-l+1)*t);
segTree[index].tab += (r-l+1)*t;
if(!(segTree[index].left == l && segTree[index].right ==
r)){ //不是恰好符合的區間,繼續更新
if(l>(segTree[index].left+segTree[index].right)/2){ // in right
area
changeTree(l,r,t,2*index+1);
}else if(r <=
(segTree[index].left+segTree[index].right)/2){
changeTree(l,r,t,2*index);
}else{
changeTree(l,(segTree[index].left+segTree[index].right)/2,t,2*index);
changeTree((segTree[index].left+segTree[index].right)/2+1,r,t,2*index+1);
}
}else{ //恰好符合的區間,添加標記
//
printf("在區域[%d-%d]添加inc=%d\n",segTree[index].left,segTree[index].right,(r-l+1)*t);
segTree[index].inc += t;
}
}
}
void searchTree(int l, int r, int index){
if(l == segTree[index].left
&& r == segTree[index].right){
//printf("在[%d-%d]區域,添加tab=%d\n",l,r,segTree[index].tab);
sum += segTree[index].tab;
}else
if(l>(segTree[index].left+segTree[index].right)/2){
//
printf("在[%d-%d]區域,添加inc=%d\n",segTree[index].left,segTree[index].right,segTree[index].inc*(r-l+1));
sum += segTree[index].inc*(r-l+1);
searchTree(l,r,2*index+1);
}else if(r <=
(segTree[index].left+segTree[index].right)/2){
//
printf("在[%d-%d]區域,添加inc=%d\n",segTree[index].left,segTree[index].right,segTree[index].inc*(r-l+1));
sum += segTree[index].inc*(r-l+1);
searchTree(l,r,2*index);
}else{
//
printf("在[%d-%d]區域,添加inc=%d\n",segTree[index].left,segTree[index].right,segTree[index].inc*(r-l+1));
sum += segTree[index].inc*(r-l+1);
searchTree(l,(segTree[index].left+segTree[index].right)/2,2*index);
searchTree((segTree[index].left+segTree[index].right)/2+1,r,2*index+1);
}
}
main(){
char order[2];
int l, r, c, i;
scanf("%d
%d",&n,&q);
buildTree(1,n,1);
for(i=1;i<=n;i++){
scanf("%d",&num[i]);
changeTree(i,i,num[i],1);
}
//
printf("----------------------------------\n\n");
for(i=1;i<=q;i++){
scanf("%s",order);
if(strcmp(order,"Q")==0){
sum = 0;
scanf("%d %d",&l, &r);
searchTree(l,r,1);
printf("%lld\n",sum);
}else{
scanf("%d %d %d",&l,&r,&c);
changeTree(l,r,c,1);
}
}
system("pause");
return 0;
}