士兵杀敌(四)

士兵杀敌(四)

时间限制: 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
 
下面是代码:原理是线段树之插线问点
01.#include<cstdio>
02. #include<cstring>
03. const int max_ = 1000002;
04.  
05. struct node
06. {
07.    int left,right;
08.    int num;
09.    node()
10.    {
11.       num = 0;
12.    }
13. };
14.  
15. struct node Line_tree[3 * max_ + 4];
16.  
17. void build(int left, int right, int i)
18.{
19.      Line_tree[i].left = left;
20.      Line_tree[i].right = right;
21.      if(left < right)
22.      {
23.         int mid = (left + right) >> 1;
24.         build(left, mid,2 * i + 1);
25.         build(mid + 1, right, 2 * i + 2);
26.      }
27. }
28. void Insert(int i, int left, int right, int num)
29. {
30.    if(left <= Line_tree[i].left && Line_tree[i].right <= right)
31.    {
32.       Line_tree[i].num += num;
33.       return ;
34.    }
35.    if(Line_tree[i].left < Line_tree[i].right)
36.    {
37.       int mid = (Line_tree[i].left + Line_tree[i].right) >> 1;
38.       if(right <= mid)
39.          Insert(2 * i + 1, left, right, num);
40.       else if(left > mid)
41.          Insert(2 * i + 2, left, right, num);
42.       else
43.       {
44.           Insert(2 * i + 1, left, mid, num);
45.           Insert(2 * i + 2, mid + 1, right, num);
46.       }
47.    }
48. }
49.  
50. int sum;
51.  
52. void Find(int i, int k)
53. {
54.    if(k >= Line_tree[i].left && k <= Line_tree[i].right)
55.    {
56.       sum += Line_tree[i].num;
57.    }
58.    if(Line_tree[i].left < Line_tree[i].right)
59.    {
60.       int mid = (Line_tree[i].left + Line_tree[i].right) >> 1;
61.       if(k <= mid)
62.          Find(2 * i + 1, k);
63.       else
64.          Find(2 * i + 2, k);
65.    }
66. }
67.  
68. int main()
69. {
70.    int T, N, x, y, num;
71.    char s[6];
72.    scanf("%d%d", &T, &N);
73.    build(0, N - 1, 0);
74.    while(T--)
75.    {
76.       scanf("%s", s);
77.       if(!strcmp(s,"ADD"))
78.       {
79.          scanf("%d%d%d", &x, &y, &num);
80.          Insert(0, x - 1, y - 1, num);
81.       }
82.       else
83.       {
84.          scanf("%d", &x);
85.          sum = 0;
86.          Find(0, x - 1);
87.          printf("%d ", sum);
88.       }
89.    }
90.    return 0;
91. }
原文地址:https://www.cnblogs.com/riskyer/p/3243821.html