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;
}

 

posted @ 2018-10-02 22:26  CaptainLi  阅读(144)  评论(0编辑  收藏  举报