D - 秋实大哥与战争
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
男儿何不带吴钩,收取关山五十州。
征战天下是秋实大哥一生的梦想,所以今天他又在练习一个对战游戏。
秋实大哥命令所有士兵从左到右排成了一行来抵挡敌人的攻击。
敌方每一次会攻击一个士兵,这个士兵就会阵亡,整个阵列就会从这个位置断开;同时有的时候已阵亡的士兵会受人赢气息感染而复活。
秋实大哥想知道某一时刻某一个士兵所在的阵列的长度是多少。
Input
第一行包含两个整数n,m,表示秋实大哥的士兵数目和接下来发生的事件数目。
接下来m行,每一行是以下三种事件之一:
0 x : 表示x位置的士兵受到攻击阵亡
1 x : 表示x位置的士兵受人赢气息感染复活
2 x : 秋实大哥想知道第x个士兵所在阵列的长度
1≤n,m≤100000,1≤x≤n。
Output
对于每一个2 x事件,输出对应的答案占一行。
Sample input and output
Sample Input | Sample Output |
---|---|
5 3 2 2 0 3 2 2 |
5 2 |
解题报告
首先说点题外话。。这题因为数据比较水,因此暴力是可以AC的。。并且跑的还比线段树快。。
当然这题我用的既不是线段树,也不是暴力。。而是set,采用的插入活人线段。。。。跑了500ms+,之后听某哥们说插死人更快。。。瞬间就纠结了
注意更新时情况较多,需一一分析(很麻烦).....
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <set> 5 using namespace std; 6 const int maxn = 1e5+50; 7 bool live[maxn]; 8 9 typedef struct data 10 { 11 int l,r; 12 friend bool operator < (const data&x , const data&y) 13 { 14 return x.l < y.l; 15 } 16 data(const int& l, const int& r) 17 { 18 this->l = l , this->r = r; 19 } 20 }; 21 22 set<data>List; 23 24 25 26 27 28 int main(int argc,char *argv[]) 29 { 30 int n,m; 31 scanf("%d%d",&n,&m); 32 memset(live,true,sizeof(live)); 33 List.insert(data(1,n)); 34 while(m--) 35 { 36 int x,y; 37 scanf("%d%d",&x,&y); 38 if (!x) 39 { 40 if (!live[y]) //已经死亡还死。。。不操作了 41 continue; 42 live[y] = false; 43 set<data>::iterator it = List.upper_bound(data(y,0)); 44 it--; 45 int getl = it->l; 46 int getr = it->r; 47 List.erase(it); 48 if (getl == y && getr == y) 49 continue; 50 if (getl == y) 51 List.insert(data(y+1,getr)); 52 else if(getr == y) 53 List.insert(data(getl,getr-1)); 54 else 55 { 56 List.insert(data(getl,y-1)); 57 List.insert(data(y+1,getr)); 58 } 59 } 60 else if(x == 1) 61 { 62 if (live[y]) //已经活了没必要再复活。。 63 continue; 64 live[y] = true; 65 if (List.size() == 0) 66 { 67 List.insert(data(y,y)); 68 continue; 69 } 70 set<data>::iterator it = List.upper_bound(data(y,0)); 71 it--; 72 if (List.size() == 1) 73 { 74 if (it == List.end()) 75 { 76 it++; 77 if(it->l == y+1) 78 { 79 int r = it->r; 80 List.erase(it); 81 List.insert(data(y,r)); 82 } 83 else 84 List.insert(data(y,y)); 85 } 86 else 87 { 88 if (it->r+1 == y) 89 { 90 int l = it->l; 91 List.erase(it); 92 List.insert(data(l,y)); 93 } 94 else 95 List.insert(data(y,y)); 96 } 97 } 98 if (List.size() >= 2) 99 { 100 set<data>::iterator it2 = it; 101 it2++; 102 if ( it2 != List.end() && it->r + 1 == y && y+1 == it2->l) 103 { 104 int l = it->l , r = it2->r ; 105 List.erase(it); 106 List.erase(it2); 107 List.insert(data(l,r)); 108 } 109 else if( it!= List.end()&& it->r + 1 == y) 110 { 111 int l = it->l; 112 List.erase(it); 113 List.insert(data(l,y)); 114 } 115 else if(it2!= List.end() && it2->l == y+1) 116 { 117 int r = it2->r; 118 List.erase(it2); 119 List.insert(data(y,r)); 120 } 121 else 122 List.insert(data(y,y)); 123 } 124 } 125 else 126 { 127 if (!live[y]) //已经死亡 128 { 129 cout << 0 << endl; 130 continue; 131 } 132 set<data>::iterator it = List.upper_bound(data(y,0)); 133 it--; 134 cout << it->r - it->l + 1 << endl; 135 } 136 } 137 return 0; 138 }
No Pain , No Gain.