Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 33098 | Accepted: 9995 |
Descriptionios
Inputexpress
Outputide
Sample Input測試
2 2 4 C 1 1 2 P 1 2 C 2 2 2 P 1 2
Sample Outputui
2 1
Sourcespa
這題第一次交的時候仍是2013年1月,過了一年多,終於把它給過了。rest
其實就是一道比較簡單的線段樹問題。code
題目的意思是說,給一條長爲L的板子,在上面進行兩種操做:P a b c表示將板上[a,b]區間內染爲c色,C a b表示詢問在板上[a,b]區間內有多少種不一樣的顏色blog
作法就是線段樹啦,樹中每一個結點維護兩個信息,Color[k]記錄結點k所表示的區間[l,r]上所染的顏色,End[k]=true意味着k結點所表示的區間[l,r]之間的顏色就是Color[k],不用再向下更新和查詢了,而End[k]=false則意味着k結點所表示的區間[l,r]之間的顏色並非Color[k],而要在它的兩了兒子結點中繼續查詢。遞歸
更細節的部分參風代碼中的註釋,很詳細的~~
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 6 using namespace std; 7 8 int L, T, O, a, b, c; 9 int color[500000]; 10 bool End[500000], haveColor[35]; 11 12 //線段樹的染色操做,將[x,y)區間染爲c色,當前操做結點爲k,所表示的區間爲[l,r) 13 void PaintColor(int c, int x, int y, int k, int l, int r) 14 { 15 //若區間[x,y)和[l,r)徹底沒有交集,則直接返回 16 if (y <= l || x >= r) 17 return; 18 //若區間[x,y)徹底覆蓋了區間[l,r),則將結點k染爲c色,並將End[k]置爲true 19 if (x <= l&&r <= y) 20 { 21 color[k] = c; 22 End[k] = true; 23 return; 24 } 25 26 //其它狀況:區間[x,y)與區間[l,r)只有部分交集 27 //若區間[l,r)之間的染色爲Color[k](即End[k]=true),則要先將當前區間的顏色傳遞下去 28 if (End[k]) 29 { 30 PaintColor(color[k], l, r, k * 2 + 1, l, (l + r) / 2); 31 PaintColor(color[k], l, r, k * 2 + 2, (l + r) / 2, r); 32 End[k] = false; 33 } 34 //遞歸地染色左兒子結點和右兒子結點 35 PaintColor(c, x, y, k * 2 + 1, l, (l + r) / 2); 36 PaintColor(c, x, y, k * 2 + 2, (l + r) / 2, r); 37 } 38 39 //查詢區間[x,y)之間有多少種不一樣的顏色,當前操做的結點爲k,表示的區間爲[l,r) 40 void CountColor(int x, int y, int k, int l, int r) 41 { 42 //若區間[x,y)和[l,r)徹底沒有交集,則直接返回 43 if (y <= l || x >= r) 44 return; 45 //若End[k]=true,則無需再向這個結點的子結點進行查詢,直接標記以後返回便可 46 if (End[k]) 47 { 48 haveColor[color[k]] = true; 49 return; 50 } 51 //其它狀況,遞歸地查詢k結點的左右兒子結點 52 CountColor(x, y, k * 2 + 1, l, (l + r) / 2); 53 CountColor(x, y, k * 2 + 2, (l + r) / 2, r); 54 } 55 56 int main() 57 { 58 while (scanf("%d %d %d", &L, &T, &O) == 3) 59 { 60 memset(End, false, sizeof(End)); 61 PaintColor(1, 1, L + 1, 0, 1, L + 1); 62 63 char ch; 64 for (int k = 1; k <= O; k++) 65 { 66 getchar(); 67 ch = getchar(); 68 scanf("%d %d", &a, &b); 69 if (a > b) 70 swap(a, b); 71 if (ch == 'C') 72 { 73 scanf("%d", &c); 74 PaintColor(c, a, b + 1, 0, 1, L + 1); 75 } 76 else if (ch == 'P') 77 { 78 memset(haveColor, false, sizeof(haveColor)); 79 CountColor(a, b + 1, 0, 1, L + 1); 80 int ans = 0; 81 for(int i=1;i<=T;i++) 82 if (haveColor[i]) 83 ans++; 84 printf("%d\n", ans); 85 } 86 } 87 } 88 89 return 0; 90 }
附一組測試數據:
Input:
10 4 5
C 2 1 3
C 9 10 2
C 5 5 4
P 1 5
P 2 2
12 5 10
C 3 2 4
C 5 4 2
P 6 5
C 1 2 2
C 2 3 2
C 4 4 1
P 2 3
P 7 7
C 8 12 5
P 1 12
6 7 4
C 1 6 2
P 1 5
C 4 2 7
P 6 1
Output:
3
1
2
1
1
3
12