bzoj4415 [Shoi2013]发牌

Posted 逢山开路 遇水架桥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4415 [Shoi2013]发牌相关的知识,希望对你有一定的参考价值。

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4415

【题解】

无脑写了splay。听说splay被卡?加了读入优化和一坨static就过了啊。。

10s卡着时限过

技术分享
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 7e5 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

namespace FIFO {
    char ch,B[1<<20],*S=B,*T=B;
    #define getc() (S==T&&(T=(S=B)+fread(B,1,1<<20,stdin),S==T)?0:*S++)
    #define isd(c) (c>=‘0‘&&c<=‘9‘)
    int aa,bb;int F(){
        while(ch=getc(),!isd(ch)&&ch!=-);ch==-?aa=bb=0:(aa=ch-0,bb=1);
        while(ch=getc(),isd(ch))aa=aa*10+ch-0;return bb?aa:-aa;
    }
}
#define gi FIFO::F()
#define BUFSIZE 5000000
namespace fob {char b[BUFSIZE]={},*f=b,*g=b+BUFSIZE-2;}
#define pob (fwrite(fob::b,sizeof(char),fob::f-fob::b,stdout),fob::f=fob::b,0)
#define pc(x) (*(fob::f++)=(x),(fob::f==fob::g)?pob:0)
struct foce {~foce() {pob; fflush(stdout);}} _foce;
namespace ib {char b[100];}
inline void pint(int x)
{
    if(x==0) {pc(48); return;}
    //if(x<0) {pc(‘-‘); x=-x;} //如果有负数就加上 
    char *s=ib::b;
    while(x) *(++s)=x%10, x/=10;
    while(s!=ib::b) pc((*(s--))+48);
}

ST int n, a[M], id[M];

namespace Splay {
    ST int ch[M][2], fa[M], sz[M], val[M], rt;
    inline void up(int x) {
        if(!x) return ;
        sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
    }
    inline void rotate(int x, int &rt) {
        int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1;
        if(rt == y) rt = x;
        else ch[z][ch[z][1] == y] = x;
        fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z;
        ch[y][ls] = ch[x][rs]; ch[x][rs] = y;
        up(y); up(x);
    }
    inline void splay(int x, int &rt) {
        while(x != rt) {
            int y = fa[x], z = fa[y];
            if(y != rt) {
                if((ch[y][0] == x)^(ch[z][0] == y)) rotate(x, rt);
                else rotate(y, rt);
            }
            rotate(x, rt);
        }
    }
    inline int find(int x, int rk) {
        if(sz[ch[x][0]]+1 == rk) return x;
        if(sz[ch[x][0]]+1 < rk) return find(ch[x][1], rk-sz[ch[x][0]]-1);
        else return find(ch[x][0], rk);
    }
    inline int get(int u) {
        RG int x = find(rt, u), y = find(rt, u+2), z;
//        cout << x << ‘ ‘ << y << endl;
        splay(x, rt); splay(y, ch[x][1]);
        z = ch[y][0];
        fa[z] = 0; ch[y][0] = 0;
        up(y); up(x);
        return val[z];
    }
    inline void build(int l, int r, int f) {
        if(l>r) return ;
        int mid = l+r>>1, x = id[mid], lst = id[f];
        if(l == r) {
            sz[x] = 1; 
            ch[x][0] = ch[x][1] = fa[x] = 0;
        } else build(l, mid-1, mid), build(mid+1, r, mid);
        val[x] = a[mid]; fa[x] = lst; up(x);
        ch[lst][mid >= f] = x;
    }
    inline void debug(int x) {
        if(!x) return ;
        printf("%d->%d, %d, sz = %d\n", x, ch[x][0], ch[x][1], sz[x]);
        debug(ch[x][0]);
        debug(ch[x][1]);
    }
}

int main() {
    n = gi;
    a[1] = a[n+2] = 0;
    for (int i=2; i<=n+1; ++i) a[i] = i-1;
    for (int i=1; i<=n+2; ++i) id[i] = i;
    Splay::build(1, n+2, 0);
    Splay::rt = (n+3)>>1;
    int lst = 0;
//    Splay::debug(Splay::rt);
    for (int i=n, t; i>=1; --i) {
        t = gi;
        lst = (lst + t) % i;
        pint(Splay::get(lst+1));
        pc(10);
    }
    return 0;
}
View Code

 

以上是关于bzoj4415 [Shoi2013]发牌的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4415 [Shoi2013]发牌

bzoj4415-4417:SHOI2013Day1题解

P3988 [SHOI2013]发牌

4418: [Shoi2013]扇形面积并|二分答案|树状数组

bzoj4418&&bzoj4419&&bzoj4420:SHOI2013Day2题解

bzoj4417: [Shoi2013]超级跳马