做完D之后我信誓旦旦以为之后就只剩一个二维就能攻克线段树了 看来也跟图论一样全是模板嘛
然后我打开了I题一眼看下去似乎直接用线段树记录sum然后跟区间长度比较然后处理一下实现也不难
两个小时后:特么的好像没那么简单啊
然后我百度了才知道原来这又是一个新题型...区间合并...啊啊啊啊啊
感谢kuangbin巨巨的blog让我学会了这个方法...
另外我WA了一天 然后上机课时候打开来重新看的时候一眼瞟到build的时候l 跟 r写反了 心痛
再多说一句 这题hdu一如既往的坑 明明有好多组数据 input上非说只有一组
#include <cstdio> #include <cmath> #include <cstring> #include <stack> #include <algorithm> #define INF 0x3f3f3f3f #define mem(str,x) memset(str,(x),sizeof(str)) #define STOP puts("Pause"); #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; typedef long long LL; const int MAXN = 50005; int n, m, ll[MAXN<<2], rl[MAXN<<2], ml[MAXN<<2]; void build(int l, int r, int rt) { ll[rt] = rl[rt] = ml[rt] = r - l + 1; if(l == r) return; int m = (l + r) >> 1; build(lson); build(rson); } void update(int p, int c, int l, int r, int rt) { if(l == r){ ll[rt] = rl[rt] = ml[rt] = c; return; } int m = (l + r) >> 1; if(p <= m) update(p, c, lson); else update(p, c, rson); if((ll[rt] = ll[rt<<1]) == m - l + 1) ll[rt] += ll[rt<<1|1]; if((rl[rt] = rl[rt<<1|1]) == r - m) rl[rt] += rl[rt<<1]; ml[rt] = max(max(ml[rt<<1], ml[rt<<1|1]), rl[rt<<1] + ll[rt<<1|1]); } int query(int p, int l, int r, int rt) { if(l == r || ml[rt] == r - l + 1 || ml[rt] == 0) return ml[rt]; int m = (l + r) >> 1; if(p <= m){ if(p > m - rl[rt<<1]){ return query(p, lson) + query(m + 1, rson); } else return query(p, lson); } else{ if(p < m + 1 + ll[rt<<1|1]){ return query(m, lson) + query(p, rson); } else return query(p, rson); } } int main() { int ask; char order[2]; stack<int> s; while(~scanf("%d%d", &n, &m)){ while(!s.empty()) s.pop(); build(1, n, 1); while(m--){ scanf("%s", order); if(order[0] == 'D'){ scanf("%d", &ask); s.push(ask); update(s.top(), 0, 1, n, 1); } else if(order[0] == 'R'){ if(!s.empty()){ update(s.top(), 1, 1, n, 1); s.pop(); } } else{ scanf("%d", &ask); printf("%d ", query(ask, 1, n, 1)); } } } return 0; }