题解 P1110 【[ZJOI2007]报表统计】

HOOCCOOH

2015-10-08 19:32:30

Solution

**STL大法好,set把你保** MIN\_SORT\_GAP用set维护,插入前lower\_bound找最接近的值,更新最小值,然后insert MIN\_GAP用堆维护,在a,b之间插入c时,把abs(a-b)从堆中删除,然后插入abs(a-c)和abs(b-c) (由于本蒟蒻只会用stl堆,不支持删除,所以用了两个堆来达到删除指定数值,具体见代码) 记得插入的时候,找到真正与当前相邻的节点,因为之前可能已经插入了一些节点,所以用链表来O(1)找到当前相邻。 代码比较丑,但比手写某树和某堆方便多了 ```cpp #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <cctype> #include <set> using namespace std; typedef long long ll; int iRead() { int ret = 0; int ch; while(!isdigit(ch = getchar()) && ch != '-'); bool bm = (ch == '-'); if(bm) ch = getchar(); while(ret = ret * 10 + (ch - '0'), isdigit(ch = getchar())); return bm ? -ret : ret; } void iReadstr(char *p) { int ch; while(isspace(ch = getchar())); while(*p++ = ch, !isspace(ch = getchar())); *p = '\0'; } const int N = 1500003; const int INF = 0x7FFFFFFF; int n, m; struct iT { int val; iT *l, *r; }ss[N], *sp = ss; iT *arr[N]; int ss1[N], *pss1 = ss1; int ss2[N], *pss2 = ss2; set<int> s; int ans2 = INF; bool iCmp(int a, int b) {return a > b;} void iUp(int val) { if(ans2) { pair<set<int>::iterator, bool> pr = s.insert(val); if(pr.second) { set<int>::iterator it; if(pr.first != s.begin()) { it = pr.first; ans2 = min(ans2, abs(*--it - val)); } if(++pr.first != s.end()) ans2 = min(ans2, abs(*pr.first - val)); } else ans2 = 0; } } int iAns1() { while(pss2 != ss2 && ss1[0] == ss2[0]) { pop_heap(ss1, pss1--, iCmp); pop_heap(ss2, pss2--, iCmp); } return ss1[0]; } void iInsert(iT *c, int val) { iT *nc = sp++; *nc = (iT){val, c, c->r}; if(c->r->val != INF) { *pss2++ = abs(c->val - c->r->val); push_heap(ss2, pss2, iCmp); } c->r->l = nc; c->r = nc; *pss1++ = abs(c->val - c->r->val); push_heap(ss1, pss1, iCmp); if(c->r->r->val != INF) { *pss1++ = abs(c->r->val - c->r->r->val); push_heap(ss1, pss1, iCmp); } } int main() { n = iRead(), m = iRead(); for(int i = 0; i < n; ++i) { int c = iRead(); arr[i] = sp++; arr[i]->val = c; iUp(c); if(i) { *pss1++ = abs(c - arr[i - 1]->val); push_heap(ss1, pss1, iCmp); } } *(arr[n] = sp++) = (iT){INF, arr[n - 1], NULL}; for(int i = 0; i < n; ++i) { if(i) arr[i]->l = arr[i - 1]; if(i != n - 1) arr[i]->r = arr[i + 1]; } char str[20]; while(m--) { int a, b; iReadstr(str); switch(str[4]) { case 'R': a = iRead(), b = iRead(); iInsert(arr[a]->l, b); iUp(b); break; case 'G': printf("%d\n", iAns1()); break; default: printf("%d\n", ans2); } } return 0; } ```