NYOJ-228 士兵杀敌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
- 5 3 2
- 样例输出
-
- 19
- 6
- 19
题目链接
一开始尝试线段树,超时,代码:
- #include<stdio.h>
- typedef struct NODE
- {
- int left, right;
- int count;
- int sum;
- }Node;
- Node array[4000000];
- void buildTree(int root, int left, int right)
- {
- array[root].left = left;
- array[root].right = right;
- if(left < right)
- {
- buildTree(root * 2, left, (left + right) / 2);
- buildTree(root * 2 + 1, (left + right) / 2 + 1, right);
- }
- }
- void add(int root, int left, int right, int count)
- {
- if(array[root].left == left && array[root].right == right)
- {
- array[root].count += count;
- return ;
- }
- else
- {
- array[root].sum += count * (right - left + 1);
- if(right < (array[root].left + array[root].right ) / 2 + 1)
- add(root * 2, left, right, count);
- else if(left > (array[root].left + array[root].right ) / 2)
- add(root * 2 + 1, left, right, count);
- else
- {
- add(root * 2, left, (array[root].left + array[root].right ) / 2, count);
- add(root * 2 + 1, (array[root].left + array[root].right ) / 2 + 1, right, count);
- }
- }
- }
- int getSum(int root, int left, int right)
- {
- if(array[root].left == left && array[root].right == right)
- return array[root].sum + array[root].count * ( right - left + 1);
- if(array[root].count != 0)
- {
- add(root * 2, array[root].left , (array[root].left + array[root].right) / 2, array[root].count );
- add(root * 2 + 1, (array[root].left + array[root].right) / 2 + 1, array[root].right, array[root].count );
- array[root].sum += array[root].count * (array[root].right - array[root].left + 1);
- array[root].count = 0;
- }
- if(left > (array[root].left + array[root].right ) / 2)
- return getSum(root * 2 + 1, left, right);
- else if(right < (array[root].left + array[root].right ) / 2 + 1)
- return getSum(root * 2, left, right);
- else
- return getSum(root * 2 , left, (array[root].left + array[root].right ) / 2) + getSum(root * 2 + 1, (array[root].left + array[root].right ) / 2 + 1, right);
- }
- void insert(int root, int i, int num)
- {
- array[root].sum += num;
- if(array[root].left == array[root].right )
- {
- return ;
- }
- if(i > (array[root].left + array[root].right ) / 2 )
- insert(root * 2 + 1, i, num);
- else
- insert(root * 2, i, num);
- }
- int main()
- {
- // freopen("in.txt", "r", stdin);
- int n ,c , q;
- int i;
- scanf("%d%d%d", &n, &c, &q);
- buildTree(1, 1, n + 1);
- int s, e, num;
- for(i = 1; i <= c; i++)
- {
- scanf("%d%d%d", &s, &e, &num);
- s ++;
- e ++;
- add(1, s, e, num);
- }
- for(i = 1; i <= q; i++)
- {
- scanf("%d%d", &s, &e);
- s ++;
- e ++;
- printf("%d\n",getSum(1, s, e));
- }
- return 0;
- }
后来在网上发现一种特殊的算法,因为本题的区间插入和查询是分开的,所以可以在插入时只在区间头和尾部加上一个增量记号,最后添加操作结束后一次性修改所有的区间,然后再遍历一遍数组修改成前N个数的和, 最后可以O(1)时间求解,总体时间复杂度为O(N).AC代码:
- #include<stdio.h>
- int array[1000010];
- int main()
- {
- int n, c, q;
- scanf("%d%d%d", &n, &c, &q);
- int i;
- int s, e, num;
- for(i = 0; i < c; i++)
- {
- scanf("%d%d%d", &s, &e, &num);
- array[s] += num;
- array[e + 1] -= num;
- }
- //第一遍把标记下的增量修改到没一个人身上
- for(i = 0; i <= n; i++)
- {
- array[i] += array[i - 1];
- }
- //第二遍求出前N个人的和
- for(i = 0; i <= n; i++)
- {
- array[i] = (array[i] + array[i - 1]) % 10003;
- }
- for(i = 0; i < q; i++)
- {
- scanf("%d %d", &s, &e);
- printf("%d\n", (array[e] - array[s - 1] + 10003) % 10003);//这里注意两个数都是10003的余数,相减要加上10003
- }
- return 0;
- }
NYOJ-228 士兵杀敌5的更多相关文章
- nyoj 228 士兵杀敌(五)
题目: http://acm.nyist.net/JudgeOnline/problem.php?pid=228 由于该题一开始是进行士兵军功增加,最后才是查找士兵的军功总和,使用一个数组,进行延迟更 ...
- NYOJ 228 士兵杀敌(五) (模拟)
{题目链接](http://acm.nyist.net/JudgeOnline/problem.php?pid=228) 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为0~M,每次有任务的时候 ...
- NYOJ 228 士兵杀敌(五)【差分标记裸题】
题目链接 所有元素初始值为0才能这么做: ①l--r全加1 a[l]++; a[r+1]--; 求一遍前缀和为元素本身. 求两遍前缀和为元素前缀和. #include<cstdio> #i ...
- NYOJ 119 士兵杀敌(三) RMQ ST
NYOJ 119 士兵杀敌(三) RMQ ST 题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=119 思路: ST在线 预处理O(nlog ...
- NYOJ 116 士兵杀敌 (线段树,区间和)
题目链接:NYOJ 116 士兵杀敌 士兵杀敌(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描写叙述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的 ...
- nyoj 108 士兵杀敌(一)
点击打开链接 士兵杀敌(一) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师, ...
- NYOJ 123 士兵杀敌4-树状数组的插线求点
士兵杀敌(四) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编 ...
- nyoj 119 士兵杀敌(三)(RMQ)
士兵杀敌(三) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进 ...
- nyoj 119 士兵杀敌(三)【线段树区间最大值最小值差】
士兵杀敌(三) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进 ...
- nyoj 116 士兵杀敌(二)【线段树单点更新+求和】
士兵杀敌(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...
随机推荐
- webstorm修改文件,webpack-dev-server不自动编译刷新的解决办法
webstorm设置中,"Settings"--"Appearance & Behavior"--"System Settings" ...
- IOS开发-PCH文件的使用
PCH文件存储一些共享的数据,在其他的文件可以直接使用,这样减少程序输入,比如存储宏定义 1.首先新建PCH文件 2.建立完毕 3.在这里找到文件路径 4.进入targets 点击Build Sttt ...
- js 字符串类型转为数组类型
以前从来没有想过这个转换,以为直接拼出来就可以了,今天同事问我这个问题,特记录如下. var test='["colkey", "col", "col ...
- WSUS目录本地迁移
生产环境中有一台win2003 server,安装了Microsoft Windows Server Update Services 3.0,作为所有windows server的内网补丁更新服务器, ...
- 设计模式的一些杂谈与反思---functionn和signals
以下关于GOF的一些例子命名不是很准确,但是大概意思差不多,懒得再去翻书了 模拟观察者模式 模拟中介者模式 模拟command模式 模拟memento和command 模拟观察者模式 观察者与职责 ...
- HDU2829
题目大意:给定一个长度为n的序列,至多将序列分成m+1段,每段序列都有权值,权值为序列内两个数两两相乘之和.m<=n<=1000. 分析:令w[i,j]表示区间[i,j]中两两乘积之和,f ...
- "unresolved external symbol __imp__WSACleanup@0"
编译时出现这种问题怎么解决:"unresolved external symbol __imp__WSACleanup@0"出现此类问题一般是ws2_32.lib这个lib没有li ...
- 内存修改console
#include <stdio.h> #include <windows.h> #include <winuser.h> int main() { int cur_ ...
- FlashBuilder(FB/eclipse) 打开多个无效
FB也即Eclipse. 想要打开多个FB,只需要新建多个FB的快捷方式,然后在路径上面加上参数 -data "具体路径" 再打开即可. 如: "C:\Program F ...
- JavaScript正则详谈
JavaScript RegExp 基础详谈 前言: 正则对于一个码农来说是最基础的了,而且在博客园中,发表关于讲解正则表达式的技术文章,更是数不胜数,各有各的优点,但是就是这种很基础的东西,如果 ...