首页 > 代码库 > UVA - 11402 Ahoy, Pirates! (线段树)

UVA - 11402 Ahoy, Pirates! (线段树)

 

In the ancient pirate ages, the Pirate Land was divided into two teams ofpirates, namely, the Buccaneer and the Barbary pirates.Each pirate’s team was not fixed, sometimes the opponent pirates attacked andhe was taken away to the other pirate team. All on a sudden a magician appearedin the Pirate Land,where he was making transition of pirates from their team to other team at hisown will. Of course, handy spells were used. The process of changing team wasknown as mutating.

 

There were N pirates and all of the pirates have a unique idfrom 0 to N-1. The great magician could mutate a bunch of pirates withconsecutive id’s to another one.

 

Suppose there were 100 pirates in the pirate land and all ofthem were Barbary pirates, then the magician could casta spell to change pirates with id’s from 10 to 33 toBuccaneer pirates. Then the whole pirate land would have 24 Buccaneer and 76 Barbarypirates.

 

The magician was very fast casting the spell. Once, Godstarted to dislike this. God had favor for the Buccaneer pirates and God askedthe magician, “Tell me, how many of the pirates of index from 2 to 30 areBuccaneer pirates?”. Now the magician was puzzled ashe was only efficient in casting spells, not in counting J

 

Being clever enough, the magician captured a clever man fromthe Earth Land.And unfortunately it’s you! Now you have to answer the God’s questions.

 

Input

 

The first line of input will contain number of test cases T.

For each test case:

The first part of the description will be of the pirateland. There could be up to N (1<=N<=1024000) pirates. Each pirate iseither assigned to Buccaneer or Barbary Pirate. Buccaneer pirates are describedby ‘1’ (ONE) and Barbary pirates are described by ‘0’(ZERO). You have to build a string of the pirates’ description. Each casestarts with an integer M (M<=100), where M pair lines follow. In each pairof lines (we call it a set), first has an integer(T<= 200) and next one has a nonempty string Pirates (consisting of 0 and 1, 0 for Barbary,1 for Buccaneer, has maximum length of 50). For each pair concatenate thestringPirates, T times.Concatenate all the resulting M sets of strings to build the piratedescription. The final concatenated string describes the pirates from index 0to end (N-1 for N pirates).

Now the next part of the input will contain queries. Firstline of next part has an integer Q describing number of queries. Eachsubsequence Q (1<=Q<=1000) lines describe each query. Each query has astring F or E or I or S and two integers, a and bdenoting indexes. The meaning of the query string arefollows:

F a b, means, mutate the pirates from index a to b to Buccaneer Pirates.

E a b, means, mutate the pirates from index a to b to Barbary Pirates.

I a b, means, mutate the pirates from index a to b to inverse pirates.

S a b, means, “God’s query” God is asking a question: “Tellme, how many Buccaneer pirates are there from index a tob?”

(a <= b, 0 <= a < n, 0<= b < n, index range are inclusive)

 

Output

For each test print the case number as the sample outputsuggests. Then for each of “God’s query”, output the query number, colon (:)and a space and the answer to the query as the sample suggest.

 

Sample Input                                                  Outputfor Sample Input

2

2

5

10

2

1000

5

F 0 17

I 0 5

S 1 10

E 4 9

S 2 10

3

3

1

4

0

2

0

2

I 0 2

S 0 8

Case 1:

Q1: 5

Q2: 1

Case 2:

Q1: 0

 

 

Explanation:

Case1:

The pirate land is as follows (N = 18)

101010101010001000

Before God’s first query it was as follows

000000111111111111


Case 2:

The pirate land is as follows (N=9)

111000000

题意:给你n个串,每个串重复若干次,再有就是三个操作:F a b 代表:将[a,b]的数变成1;E a b 代表:将区间[a,b]变成0;I a b 代表:取反;S a b 代表:计算[a,b]1的个数

思路:看了队友一个很巧妙的操作:0代表不变,1代表1,2代表2,3代表取反,其他的就是线段树的延迟标记了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson(x) ((x << 1) + 1)
#define rson(x) ((x << 1) + 2)
using namespace std;
const int maxn = 1024000;

struct Node {
	int l, r, num, flag;
	Node() {}
	Node(int l, int r) {
		this->l = l, this->r = r;
		num = flag = 0;
	}
	int len() {
		return r - l + 1;
	}
} node[maxn<<2];
int s[maxn];
char str[maxn];

void pushup(int pos) {
	node[pos].num = node[lson(pos)].num + node[rson(pos)].num;
}

void build(int pos, int l, int r) {
	node[pos] = Node(l, r);
	if (l == r) {
		node[pos].num = s[l];
		return;
	}
	int m = (node[pos].l + node[pos].r) >> 1;
	build(lson(pos), l, m);
	build(rson(pos), m+1, r);
	pushup(pos);
}

int getOp(int a, int b) {
	if (a == 3 && b == 3) return 0;
	if (a == 3 && b == 1) return 2;
	if (a == 3 && b == 2) return 1;
	if (a == 3 && b == 0) return 3;
	if (a == 2) return 2;
	if (a == 1) return 1;
	return 0;
}

void pushdown(int pos) {
	if (node[pos].flag) {
		int lo = getOp(node[pos].flag, node[lson(pos)].flag);
		node[lson(pos)].flag = lo;
		if (node[pos].flag == 2) node[lson(pos)].num = 0;
		if (node[pos].flag == 1) node[lson(pos)].num = node[lson(pos)].len();
		if (node[pos].flag == 3) node[lson(pos)].num = node[lson(pos)].len() - node[lson(pos)].num;

		int ro = getOp(node[pos].flag, node[rson(pos)].flag);
		node[rson(pos)].flag = ro;
		if (node[pos].flag == 2) node[rson(pos)].num = 0;
		if (node[pos].flag == 1) node[rson(pos)].num = node[rson(pos)].len();
		if (node[pos].flag == 3) node[rson(pos)].num = node[rson(pos)].len() - node[rson(pos)].num;
		node[pos].flag = 0;
	}
}

void update(int pos, int l, int r, int v) {
	if (node[pos].l >= l && node[pos].r <= r) {
		int ts = getOp(v, node[pos].flag);
		if (v == 1)
			node[pos].num = node[pos].len();
		else if (v == 2)
			node[pos].num = 0;
		else node[pos].num = node[pos].len() - node[pos].num;
		node[pos].flag = ts;
		return;
	}

	pushdown(pos);
	int m = (node[pos].l + node[pos].r) >> 1;
	if (l <= m)
		update(lson(pos), l, r, v);
	if (r > m)
		update(rson(pos), l, r, v);
	pushup(pos);
}

int query(int pos, int l, int r) {
	if (node[pos].l >= l && node[pos].r <= r) 
		return node[pos].num;
	int ans = 0;
	pushdown(pos);
	int m = (node[pos].l + node[pos].r) >> 1;
	if (l <= m)
		ans += query(lson(pos), l, r);
	if (r > m)
		ans += query(rson(pos), l, r);
	pushup(pos);
	return ans;
}

int main() {
	int t, n, cnt, m, cas = 1;
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		cnt = 0;
		while (n--) {
			scanf("%d", &m);	
			scanf("%s", str);
			int len = strlen(str);
			while (m--) {
				for (int i = 0; i < len; i++)
					s[cnt++] = str[i] - '0';
			}
		}

		build(0, 0, cnt-1);
		int q;
		scanf("%d", &q);
		char que[5];
		int a, b, c;
		printf("Case %d:\n", cas++);
		int qn = 1;
		while (q--) {
			scanf("%s%d%d", que, &a, &b);
			if (que[0] == 'F') update(0, a, b, 1);
			if (que[0] == 'E') update(0, a, b, 2);
			if (que[0] == 'I') update(0, a, b, 3);
			if (que[0] == 'S') printf("Q%d: %d\n", qn++, query(0, a, b));
		}
	}
	return 0;
}


UVA - 11402 Ahoy, Pirates! (线段树)