NYOJ-Soldiers Kill Enemy (4) Line Segment Tree, Interval Number, Tree Array

Keywords: less

Soldiers Kill the Enemy (4)

Time limit: 2000 ms | memory limit: 65535 KB
Difficulty: 5
describe

There are millions of elite soldiers under the command of General Nan. Now there are known to be M soldiers, numbered 1-M. Every time there are tasks, there will always be a group of people with similar numbers to fight together (people with similar numbers are often together and familiar with each other). Eventually, their military merits will be divided equally among everyone. Sometimes, it will be calculated which one of them actually has how many troops. Gong is a relatively difficult thing. The task of the military division laborers is to report the military achievements of a certain person quickly when General Nan asks him about his military achievements. Please write a program to help the laborers.

Let's assume that all men start with zero military merit.

input There is only one set of test data.
Each line is two integers T and M, representing a total of T instructions, M soldiers. (1<=T, M<=1000000)
Subsequent T lines, each of which is an instruction.
Directives are divided into two types:
A form like
ADD 100 500 55 said that the 100 to 500 people fought, and eventually each person won an average of 55 military merits, each time the number of military merits won by each person will not exceed 100, not less than - 100.
The second form is as follows:
QUERY 300 said General Nan was asking the 300 men what their military merits were. output For each query to output this person's military work, the output of each query occupies one line.
sample input
4 10
ADD 1 3 10
QUERY 3
ADD 2 6 50
QUERY 3
sample output
10

60


This problem will be timed out by using ordinary segment tree, so we need to use interval tree. Blog with interval number will write blog later. Another method is tree array. Here are the codes of two methods to solve the problem:


Ordinary segment tree code (timeout)

#include <cstdio>
#include <iostream>
using namespace std;
#define Max 1000000
int sum[Max<<2];
int co[Max<<2];
void pushdown(int rt, int k)
{
	if(co[rt]) {
		co[rt<<1] += co[rt];
		co[rt<<1|1] += co[rt];
		sum[rt<<1] += co[rt] * (k - (k >> 1));
		sum[rt<<1|1] += co[rt] * (k >> 1);
		co[rt] = 0;
	}
}
void Build(int l, int r, int rt)
{
	sum[rt] = 0;
	if(l == r) return ;
	int m = (l + r) >> 1;
	Build(l, m, rt<<1);
	Build(m+1, r, rt<<1|1);
	sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void update(int L, int R, int c, int l, int r, int rt)
{
	if(l >= L && R >= r) {
		sum[rt] += c;
		co[rt] += c;
		return ;
	}
	pushdown(rt, r - l + 1);
	int m = (l + r) >> 1;
	if(L <= m) update(L, R, c, l, m, rt<<1);
	if(m < R) update(L, R, c, m+1, r, rt<<1|1);
	sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
int quest(int l, int r, int t, int rt)
{
	if(l == r) return sum[rt];
	pushdown(rt, r - l + 1);
	int m = (l + r) >> 1;
	int res = 0;
	if(t <= m) res = quest(l, m, t, rt<<1);
	if(t > m) res = quest(m+1, r, t, rt<<1|1);
	return res;
}
int main()
{
	int T, M, a, b, c, t;
	char str[3];
	scanf("%d%d", &T, &M);
	while(T--) {
		scanf("%s",str);
		if(str[0] == 'A') {
			scanf("%d%d%d", &a, &b, &c);
			update(a, b, c, 1, M, 1);
		} else {
			scanf("%d", &t);
			printf("%d\n", quest(1, M, t, 1));
		}
	}
	return 0;
}


Interval tree code (ac)

#include <iostream>
#include<algorithm>
#include <cstdio>
#include <cstring>
#define MAXN 1000100
using namespace std;
struct node {
	int l, r;
	int val;
};
node T[MAXN * 4 + 10];
void build(int root, int begin, int end) {
	T[root].l = begin;
	T[root].r = end;
	T[root].val = 0;
	if(begin < end) {
		int mid = (begin + end) >> 1;
		build(root << 1, begin, mid);
		build(root << 1 | 1, mid + 1, end);
	}
}
void updata(int root, int l, int r, int add) {
	if(T[root].l >= l && T[root].r <= r) {
		T[root].val += add;
	}
	else {
		int mid = (T[root].l + T[root].r) >> 1;
		if(r <= mid) updata(root << 1, l, r, add);
		else if(l > mid) updata(root << 1 | 1, l, r, add);
		else {
			updata(root << 1, l, mid, add);
			updata(root << 1 | 1, mid + 1, r, add);
		}
	}
}
int query(int root, int id) {
	if(T[root].l == T[root].r) {
		return T[root].val;
	}
	else {
		int sum = T[root].val;
		int mid = (T[root].l + T[root].r) >> 1;
		if(id <= mid) sum += query(root << 1, id);
		else sum += query(root << 1 | 1, id);
		return sum;
	}
}
int main() {
    int t, M;
    scanf("%d %d", &t, &M);
    build(1, 1, M);
	char str[10];
    while(t--) {
    	scanf("%s", str);
    	if(str[0] == 'A') {
    		int l, r, add;
    		scanf("%d %d %d", &l, &r, &add);
    		updata(1, l, r, add);
		}
		else {
			int id;
			scanf("%d", &id);
			printf("%d\n", query(1, id));
		}
	}
    return 0;
}


Tree array (ac)

#include<cstdio>
#include<cstring>
const int M=1000010;
int data[M];
int Max;
inline int LowBit(int n)
{
	return n&(-n);
}
void Plus(int n,int value) //Increase value for each of the first n items
{
	while(n>0)
	{
		data[n]+=value;
		n-=LowBit(n);
	}
}
int Get(int n) //Get the value of each location
{
	int sum=0;
	while(n<=Max)
	{
		sum+=data[n];
		n+=LowBit(n);
	}
	return sum;
}
char cmd[50];
int main()
{
	int n,a,b,v;
	scanf("%d%d",&n,&Max);
	while(n--)
	{
		scanf("%s",cmd);
		if(!strcmp(cmd,"ADD"))
		{
			scanf("%d%d%d",&a,&b,&v);
			Plus(a-1,-v);
			Plus(b,v);
		}
		else
		{
			scanf("%d",&a);
			printf("%d\n",Get(a));
		}
	}
}        

Posted by jdavila28 on Thu, 13 Jun 2019 12:45:04 -0700