ZJOI2007 报表统计
这道题还是相当的有意思的。
一开始我有个非常沙雕的想法。既然他要求在愿序列后面插值,这么优秀的操作,当然是要用vector实现啦!然后每次往里插值都会影响到其前后一位,直接这么更新就完事啦!下面那一项用平衡树维护每次找一下前驱后继,更新差值的最小值就好啦!
然后愉快的交上去爆零了……
回来一想……你确实影响了前后一位,但是也同时会影响到最小值啊……
啊!那好,我们用multi set!
然后交上去T了。
STL大军的威力得开O2才能显现!
然后又惊奇的发现自己写了一份只能过大数据的程序233333.
后来又发现……你往里插数的时候也不会影响前面一位数和更前面一位数……你把他俩差值删了干什么……于是交上去A了。
ovo好吧这不是练splay,这是看自己智商有多低。
// luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<cstring> #include<vector> #include<set> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar('\n') #define de putchar('#') #define pr pair<int,int> #define mp make_pair #define fi first #define sc second #define pb push_back using namespace std; typedef long long ll; const int M = 500005; const int N = 10000005; const int INF = 1000000009; int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >='0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return ans * op; } struct node { int fa,ch[2],size,cnt,val; }t[M<<1]; vector <int> v[M]; multiset<int> q; multiset<int> :: iterator it; int n,m,x,root,tot,minn = INF,minx = INF,idx,a; char s[15]; bool get(int x) { return t[t[x].fa].ch[1] == x; } void pushup(int x) { t[x].size = t[t[x].ch[0]].size + t[t[x].ch[1]].size + t[x].cnt; } void rotate(int x) { int y = t[x].fa,z = t[y].fa,k = get(x); t[z].ch[t[z].ch[1] == y] = x,t[x].fa = z; t[y].ch[k] = t[x].ch[k^1],t[t[y].ch[k]].fa = y; t[x].ch[k^1] = y,t[y].fa = x; pushup(x),pushup(y); } void splay(int x,int goal) { while(t[x].fa != goal) { int y = t[x].fa,z = t[y].fa; if(z != goal) (t[y].ch[1] == x) ^ (t[z].ch[1] == y) ? rotate(x) : rotate(y); rotate(x); } if(!goal) root = x; } bool insert(int x) { int u = root,f = 0; bool flag = 0; while(u && x != t[u].val) f = u,u = t[u].ch[x > t[u].val]; if(u) t[u].cnt++,flag = 1; else { u = ++idx; if(f) t[f].ch[x > t[f].val] = u; t[u].ch[0] = t[u].ch[1] = 0; t[u].fa = f,t[u].val = x,t[u].size = t[u].cnt = 1; } splay(u,0); return flag; } int pre() { int u = t[root].ch[0]; if(!u) return INF; while(t[u].ch[1]) u = t[u].ch[1]; return t[u].val; } int next() { int u = t[root].ch[1]; if(!u) return INF; while(t[u].ch[0]) u = t[u].ch[0]; return t[u].val; } void modi(int x,int a) { int l = (int)(v[x].size()-1); if(x != n) { it = q.find(abs(v[x][l]-v[x+1][0])); if(it != q.end()) q.erase(it); } v[x].pb(a); q.insert(abs(v[x][l+1]-v[x][l])); if(x != n) q.insert(abs(v[x][l+1]-v[x+1][0])); } int main() { n = read(),m = read();insert(INF),insert(-INF); x = read(),v[1].pb(x),insert(x); rep(i,2,n) { x = read(),v[i].pb(x),q.insert(abs(v[i][0]-v[i-1][0])); if(insert(x)) minx = 0; if(minx == 0) continue; int a1 = pre(),a2 = next(); minx = min(minx,min(abs(a1-x),abs(a2-x))); } //printf("%d\n",*(q.begin())); rep(i,1,m) { scanf("%s",s); if(s[0] == 'I') { x = read(),a = read(); modi(x,a); if(insert(a)) minx = 0; if(minx == 0) continue; int a1 = pre(),a2 = next(); //printf("#%d %d\n",a1,a2); minx = min(minx,min(abs(a1-a),abs(a2-a))); } else if(s[4] == 'G') printf("%d\n",*(q.begin())); else if(s[4] == 'S') printf("%d\n",minx); } return 0; }
当你意识到,每个上一秒都成为永恒。