士兵杀敌(四)(树状数组+线段树)

士兵杀敌(四)

时间限制:2000 ms  |  内存限制:65535 KB
难度:5
 
描述

南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情,军师小工的任务就是在南将军询问他某个人的军功的时候,快速的报出此人的军功,请你编写一个程序来帮助小工吧。

假设起始时所有人的军功都是0.

 
输入
只有一组测试数据。 每一行是两个整数T和M表示共有T条指令,M个士兵。(1<=T,M<=1000000) 随后的T行,每行是一个指令。 指令分为两种: 一种形如 ADD 100 500 55 表示,第100个人到第500个人请战,最终每人平均获得了55军功,每次每人获得的军功数不会超过100,不会低于-100。 第二种形如: QUERY 300 表示南将军在询问第300个人的军功是多少。
输出
对于每次查询输出此人的军功,每个查询的输出占一行。
样例输入
4 10
ADD 1 3 10
QUERY 3
ADD 2 6 50
QUERY 3
样例输出
10
60

树状数组:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define mem(x,y) memset(x,y,sizeof(x))
#define L tree[root].l
#define R tree[root].r
#define S tree[root].sum
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
#define LA tree[root].lazy
#define V tree[root].val
const int INF=0x3f3f3f3f;
const int MAXN=1000010;
int tree[MAXN];
int lowbit(int x){
    return x&(-x);
}
int update(int x,int v){
    while(x<MAXN){
        tree[x]+=v;
        x+=lowbit(x);
    }
}
int query(int x){
    int ans=0;
    while(x>0){
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans;
}
int main(){
    int M,T,a,b,c;
    char s[10];
    scanf("%d%d",&T,&M);
    mem(tree,0);
    while(T--){
        scanf("%s",s);
        if(strcmp(s,"ADD")==0){
            scanf("%d%d%d",&a,&b,&c);
            update(a,c);update(b+1,-c);
        }
        else{
            scanf("%d",&a);
            printf("%d
",query(a));
        }
    }
    return 0;
}

线段树:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 #define mem(x,y) memset(x,y,sizeof(x))
 8 #define L tree[root].l
 9 #define R tree[root].r
10 #define S tree[root].sum
11 #define lson root<<1,l,mid
12 #define rson root<<1|1,mid+1,r
13 #define LA tree[root].lazy
14 #define V tree[root].val
15 #define NOW S=tree[root<<1].sum+tree[root<<1|1].sum
16 const int INF=0x3f3f3f3f;
17 const int MAXN=1000010;
18 struct Node{
19     int l,r,sum;//lazy,val;
20 }; 
21 Node tree[MAXN<<2];
22 int ans;
23 void build(int root,int l,int r){
24     L=l;R=r;S=0;//LA=0;V=0;
25     if(l==r)return;
26     else{
27         int mid=(l+r)>>1;
28         build(lson);build(rson);
29     }
30 }
31 void update(int root,int l,int r,int v){
32     if(L>=l&&R<=r){
33     //    LA=1;
34     //    V=v;
35         S+=v;
36     }
37     else{
38         int mid=(L+R)>>1;
39         /*if(LA){
40             LA=0;
41             update(root<<1,l,mid,V);
42             update(root<<1|1,mid+1,r,V);
43             V=0;
44         }*/
45         if(mid>=r)update(root<<1,l,r,v);
46         else if(mid<l)update(root<<1|1,l,r,v);
47         else{
48             update(root<<1,l,mid,v);
49             update(root<<1|1,mid+1,r,v);
50         }
51     }
52 }
53 int query(int root,int x){
54     if(L==x&&R==x)return S;
55         int cnt=S;
56         int mid=(L+R)>>1;
57         if(mid>=x)cnt+=query(root<<1,x);
58         else cnt+=query(root<<1|1,x);
59         return cnt;
60 }
61 int main(){
62     int T,M;
63     char s[10];
64     int a,b,c;
65     scanf("%d%d",&T,&M);
66     build(1,1,M);
67     while(T--){
68         scanf("%s",s);
69         if(strcmp(s,"ADD")==0){
70             scanf("%d%d%d",&a,&b,&c);
71             update(1,a,b,c);
72         }
73         else{
74             scanf("%d",&a);
75             printf("%d
",query(1,a));
76         }
77     }
78     return 0;
79 }
原文地址:https://www.cnblogs.com/handsomecui/p/4954393.html