zoukankan      html  css  js  c++  java
  • 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('
    ')
    #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
    ",*(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
    ",a1,a2);
            minx = min(minx,min(abs(a1-a),abs(a2-a)));
        }
        else if(s[4] == 'G') printf("%d
    ",*(q.begin()));
        else if(s[4] == 'S') printf("%d
    ",minx);
        }
        return 0;
    }
  • 相关阅读:
    二维数组的使用及其内存结构
    一维数组的练习
    数组的默认初始化
    数组
    完数
    break与continue
    乘法表及质数的输出法
    嵌套循环的使用
    Elasticsearch索引和查询性能调优
    elasticsearch数据冷热分离、数据冷备
  • 原文地址:https://www.cnblogs.com/captain1/p/9738710.html
Copyright © 2011-2022 走看看