士兵杀敌(五)
时间限制:
2000 ms | 内存限制:
65535 KB
难度:
5
-
描述
-
南将军麾下有百万精兵,现已知共有M个士兵,编号为0~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情。
在这样的情况下,南将军却经常会在许多次战役之后询问军师小工第i号士兵到第j号士兵所有人的总军功数。
请你帮助军师小工回答南将军的提问。
-
输入
-
只有一组测试数据
第一行是三个整数N,C,Q(1<=N,C,Q<=1000000),其中N表示士兵的总数。
随后的C行,每行有三个整数Mi,Ni,Ai(0<=Mi<=Ni<=N,0<=Ai<=100),表示从第Mi号到第Ni号士兵所有人平均增加了Ai的军功。
再之后的Q行,每行有两个正正数m,n,表示南将军询问的是第m号士兵到第n号士兵。
输出
- 请对每次询问输出m号士兵到第n号士兵的总军功数,由于该数值可能太大,请把结果对10003取余后输出 样例输入
-
5 3 2 1 3 2 2 4 1 5 5 10 1 5 2 3
样例输出
-
19
6
-
-
这题本想用线段树,但写了一半又不会写了。。。听大神说这题用线段树很不好过,然后我就去看了直接用数组的做法,真的是很巧妙,看了半天才看懂。。膜拜。 据说这是一道离线题。但是对于这道题的测试数据表示不理解。说了N表示士兵的总数,又说了编号从0开始,那么N等于5时为什么会出现编号是5的士兵???不太懂。。。恳求解答。不过即使这样,把数组开到0到n也就可以过了。详见代码。
-
参考博客:http://blog.csdn.net/dgq8211/article/details/7496402 感谢!!
-
-
#include <iostream> #include<algorithm> #include <cstdio> #include <cstring> #define MAXN 1000100 using namespace std; int num[MAXN] = {0}; int main() { //freopen("input.txt", "r", stdin); int N, C, Q; scanf("%d %d %d", &N, &C, &Q); int i; for(i = 0; i < C; i++) { int l, r, add; scanf("%d %d %d", &l, &r, &add); num[l] += add; num[r + 1] -= add; } for(i = 1; i <= N; i++) { num[i] += num[i - 1]; //这样可以计算出每个士兵的杀敌数。 } for(i = 1; i <= N; i++) { num[i] = (num[i] + num[i - 1]) % 10003; //num[i]表示前i个士兵(包括i)的总杀敌数 。 } int m, n; for(i = 0; i < Q; i++) { scanf("%d %d", &m, &n); printf("%d\n", (num[n] - num[m - 1] + 10003) % 10003); //+10003是因为由于上一步保存的是余数的值,所以可能导致num[i]<num[i-1]。 } return 0; }
-
只有一组测试数据