nyoj228 士兵杀敌(五)(区间更新,区间查询)

士兵杀敌(五)

时间限制: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
来源
[张云聪]原创
上传者
张云聪

好机智的一道题  看了别人的题解 看了好久才理解

就是在更新的时候 用一个数组维护 比如要在【a,b】之间增加x,那么就让count[a]+=x,count[b+1]-=x。最后更新完以后

	for(int i=1;i<=max;i++)
	{
		count[i]=count[i]+count[i-1];
	//	sum[i]=(sum[i-1]+count[i])%mod;
	}

使用这个for循环 就能把更新的总人数 准确得得出  慢慢理解  哈哈

#include <stdio.h>
#include <string.h>
#define N 1000000+10
#define mod 10003
int count[N];
int sum[N];
int main()
{
	int n,c,q;
	memset(count,0,sizeof(count));
	memset(sum,0,sizeof(sum));
	scanf("%d %d %d",&n,&c,&q);
	int max=0;
	for(int i=0;i<c;i++)
	{
		int a,b,x;
		scanf("%d %d %d",&a,&b,&x);
		count[a]+=x;
		count[b+1]-=x;
		if(b>max)
		max=b;
	}
	sum[0]=count[0];
	for(int i=1;i<=max;i++)
	{
		count[i]=count[i]+count[i-1];
		sum[i]=(sum[i-1]+count[i])%mod;
	}
	for(int i=0;i<q;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		if(a)
		printf("%d\n",(sum[b]-sum[a-1]+10003)%mod);
		else
		printf("%d\n",sum[b]%mod);
	}
	return 0;
}
时间: 2024-09-30 05:16:38

nyoj228 士兵杀敌(五)(区间更新,区间查询)的相关文章

POJ 1195-Mobile phones(二维树状数组-区间更新区间查询)

Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 17661   Accepted: 8173 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The

POJ-3468(线段树+区间更新+区间查询)

A Simple Problem With Integers POJ-3468 这题是区间更新的模板题,也只是区间更新和区间查询和的简单使用. 代码中需要注意的点我都已经标注出来了,容易搞混的就是update函数里面还需要计算sum数组.因为这里查询的时候是直接用sum查询结点. //区间更新,区间查询 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #inc

POJ 3468 A Simple Problem with Integers 线段树 区间更新 区间查询

题目链接: http://poj.org/problem?id=3468 题目描述: 一组数列, 可进行一段区间加上某一个数, 和区间查询 解题思路: 线段树, 之前的那道题是求总区间直接输出sum[1] 就可以了, 这次有了区间查询, 同理, 查询的时候Pushdown 代码: #include <iostream> #include <cstdio> #include <string> #include <vector> #include <map

树状数组区间更新区间查询以及gcd的logn性质

题目描述 给你一个长为n的序列a m次查询 每次查询一个区间的所有子区间的gcd的和mod1e9+7的结果 输入描述: 第一行两个数n,m之后一行n个数表示a之后m行每行两个数l,r表示查询的区间 输出描述: 对于每个询问,输出一行一个数表示答案 示例1 输入 5 7 30 60 20 20 20 1 1 1 5 2 4 3 4 3 5 2 5 2 3 输出 30 330 160 60 120 240 100 说明 [1,1]的子区间只有[1,1],其gcd为30[1,5]的子区间有:[1,1]

CDOJ 1057 秋实大哥与花 线段树 区间更新+区间查询

链接: I - 秋实大哥与花 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%lld & %llu Submit Status Practice UESTC 1057 Appoint description:  System Crawler  (2016-04-19) Description 秋实大哥是一个儒雅之人,昼听笙歌夜醉眠,若非月下即花前. 所以秋实大哥精心照料了很多花朵.现在所有的花朵排成了一行,每朵花有一

树状数组区间更新区间查询

1 void ins(int k,int x,int t){ 2 for (; x<=tot; x+=x&-x) c[k][x]+=t; 3 } 4 ll getsum(int k,int x){ 5 ll t=0; for (; x; x-=x&-x) t+=c[k][x]; return t; 6 } 7 void mdy(int x,int y,int z){ 8 ins(0,x,z); ins(1,x,z*(x-1)); ins(0,y+1,-z); ins(1,y+1,-z

nyoj 116 士兵杀敌(四)(线段树区间更新和单点查询)

题目123 题目信息 运行结果 本题排行 讨论区 士兵杀敌(四) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情,军师小工的任务就是在南将军询问他某个人的军功的时候,快速的报出此人的军功,请你编写一个程序来

ny 116 士兵杀敌(二) -- 线段树(单点更新,区间求和)

士兵杀敌(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧. 南将军的某次询问之后士兵i可能又杀敌q人,之后南将军再询问的时候,需要考虑到新增的杀敌数. 输入 只有一组测试数据 第一行是两个整数N,M,其中N表示士兵的个数(1<N<1000000),M表示指令的条数.(1<M<1000

ny 123 士兵杀敌(四)-- 线段树(区间更新,单点查询)

士兵杀敌(四) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战(编号相近的人经常在一块,相互之间比较熟悉),最终他们获得的军功,也将会平分到每个人身上,这样,有时候,计算他们中的哪一个人到底有多少军功就是一个比较困难的事情,军师小工的任务就是在南将军询问他某个人的军功的时候,快速的报出此人的军功,请你编写一个程序来帮助小工吧. 假设起始时所有人的军功都是0. 输入