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; }
以上是关于bzoj4415 [Shoi2013]发牌的主要内容,如果未能解决你的问题,请参考以下文章
4418: [Shoi2013]扇形面积并|二分答案|树状数组