zoukankan      html  css  js  c++  java
  • 【JSOI2008】最大数

    https://www.luogu.org/problem/show?pid=1198

    之前刚学完Splay想找题练手的时候做的,写完Splay交上去了才发现这应该是线段树裸题23333

    Splay解法

    按照要求操作即可……

    #include <iostream>
    using namespace std;
    int m, d, t;
    const int inf = 0x7fffffff;
    namespace splay
    {
    struct node;
    node *nil = 0, *root;
    struct node
    {
        int val, size, maxnum;
        node *ch[2];
        node(int v) : val(v), size(1), maxnum(v)
        {
            ch[0] = ch[1] = nil;
        }
        void pull_up()
        {
            size = ch[0]->size + ch[1]->size + 1;
            maxnum = max(val, max(ch[0]->maxnum, ch[1]->maxnum));
        }
        int cmp(int k)
        {
            if(this == nil || k == ch[0]->size + 1)
                return -1;
            else
                return (k <= ch[0]->size) ? 0 : 1;
        }
    };
    void init()
    {
        if(!nil)
            nil = new node(-inf);
        nil->size = 0;
        nil->ch[0] = nil->ch[1] = nil;
        root = new node(-inf);
        root->ch[1] = new node(-inf);
        root->size = 2;
    }
    void rotate(node *&t, int d)
    {
        node *k = t->ch[d ^ 1];
        t->ch[d ^ 1] = k->ch[d];
        k->ch[d] = t;
        t->pull_up();
        k->pull_up();
        t = k;
    }
    void splay(int k, node *&t = root)
    {
        int d1 = t->cmp(k);
        if(d1 == 1)
            k = k - t->ch[0]->size - 1;
        if(d1 != -1)
        {
            int d2 = t->ch[d1]->cmp(k);
            if(d2 != -1)
            {
                int k2 = (d2 == 1) ? (k - t->ch[d1]->ch[0]->size - 1) : k;
                splay(k2, t->ch[d1]->ch[d2]);
                if(d1 != d2)
                {
                    rotate(t->ch[d1], d2 ^ 1);
                    rotate(t, d1 ^ 1);
                }
                else
                {
                    rotate(t, d1 ^ 1);
                    rotate(t, d2 ^ 1);
                }
            }
            else
                rotate(t, d1 ^ 1);
        }
    }
    void insert(int val)
    {
        splay(root->size - 1);
        node *k = root->ch[1];
        root->ch[1] = new node(val);
        root->ch[1]->ch[1] = k;
        k->pull_up();
        root->ch[1]->pull_up();
        root->pull_up();
    }
    int get_maxnum(int len)
    {
        int from = root->size - len;
        int to = from + len - 1;
        splay(to + 1, root);
        splay(from - 1, root->ch[0]);
        return root->ch[0]->ch[1]->maxnum;
    }
    }
    int main()
    {
        using namespace splay;
        cin >> m >> d;
        init();
        char a;
        int b;
        while(m--)
        {
            cin >> a >> b;
            switch(a)
            {
            case 'A':
                insert((b + t) % d);
                break;
            case 'Q':
                t = get_maxnum(b);
                cout << t << endl;
                break;
            }
        }
        return 0;
    }

    线段树解法

    M<=2e5,也就是极限状况下最多2e5个数。开个长度是2e5的线段树,再记录下已经加了N个数了。每次插入就是更改第N+1个元素,查询就是查询区间[N-L+1,N]的最大值。

    懒得重写一遍了……

  • 相关阅读:
    app缓存设计-文件缓存
    设计模式-模板方式
    设计模式-观察者模式
    java 类加载顺序
    Java项目添加log4j日志文件错误记录
    如何在eclipse中配置反编译工具JadClipse
    eclipse反编译插件jadClipse安装使用教程
    StringUtils工具类的isBlank()方法使用说明
    SLF4J: Failed to load class的问题及解决
    GitHub的Fork 是什么意思
  • 原文地址:https://www.cnblogs.com/ssttkkl/p/7606268.html
Copyright © 2011-2022 走看看