bzoj 4415: [Shoi2013]发牌

4415: [Shoi2013]发牌

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 173  Solved: 124
[Submit][Status][Discuss]

Description

假设一开始,荷官拿出了一副新牌,这副牌有N张不同的牌,编号依次为1到N。由于是新牌,所以牌是按照顺序排好的,从牌库顶开始,依次为1, 2,……直到N,N号牌在牌库底。为了发完所有的牌,荷官会进行N次发牌操作,在第i次发牌之前,他会连续进行R_i次销牌操作,R_i由输入给定。请问最后玩家拿到这副牌的顺序是什么样的?

举个例子,假设N = 4,则一开始的时候,牌库中牌的构成顺序为{1, 2, 3, 4}。

假设R1=2,则荷官应该连销两次牌,将1和2放入牌库底,再将3发给玩家。目前牌库中的牌顺序为{4, 1, 2}。

假设R2=0,荷官不需要销牌,直接将4发给玩家,目前牌库中的牌顺序为{1,2}。

假设R3=3,则荷官依次销去了1, 2, 1,再将2发给了玩家。目前牌库仅剩下一张牌1。

假设R4=2,荷官在重复销去两次1之后,还是将1发给了玩家,这是因为1是牌库中唯一的一张牌。

Input

第1行,一个整数N,表示牌的数量。第2行到第N + 1行,在第i + 1行,有一个整数R_i, 0≤R_i<N

Output

第1行到第N行:第i行只有一个整数,表示玩家收到的第i张牌的编号。

Sample Input

4
2
0
3
2

Sample Output

3
4
2
1

HINT

N<=70万



最自然的思想:在树状数组中跑二分。

k的意义是当前n个数字中的答案是第几大的。 O(nlogn^2)迷之水过

(当然可以改成线段树,这样就不要二分了,哪边符合往哪边走O(nlogn))


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<cstring>
 8 #define yyj(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout);
 9 #define llg long long
10 #define maxn 700010
11 llg i,j,k,x,n,m,T,y,l,r,c[maxn];
12 using namespace std;
13 llg lowbit(llg x) {return x&-x;}
14 void add(llg x,llg val){while (x<=y) {c[x]+=val; x+=lowbit(x);}}
15 llg sum(llg x) {llg ans=0; while (x>0) {ans+=c[x]; x-=lowbit(x);} return ans;}
16 int main()
17 {
18     yyj("a");
19     cin>>n; y=n;
20     for (i=1;i<=n;i++) add(i,1);
21     k=1;
22     while (n--)
23     {
24         scanf("%lld",&m);
25         k=(k+m-1)%(n+1)+1;
26         l=1; r=y;
27         while (l!=r)
28         {
29             llg mid=(l+r)/2;
30             llg w=sum(mid);
31             if (w>=k) r=mid; else l=mid+1;
32         }
33         printf("%lld\n",l);
34         add(l,-1);
35         //k++;
36     }
37     return 0;
38 }

倒数第二还有谁?

时间: 2024-10-19 03:45:04

bzoj 4415: [Shoi2013]发牌的相关文章

P3988 [SHOI2013]发牌

题目 P3988 [SHOI2013]发牌 做法 我们切牌时的状态: 手玩几次后我们发现切\(K\)次牌就是求堆顶一下的\(K+1\)大值,套上主席树就好了 My complete code #include<cstdio> #include<cstring> #include<cstdio> #include<algorithm> #include<iostream> using namespace std; typedef long long

BZOJ 4415 发牌

线段树就好了啊. 为什么一眼splay啊... 其实splay也能过,但是线段树更方便? #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 700500 using namespace std; int n,r,root,tot=0,ls[maxn<<2],rs[maxn<<2],val[maxn<<

BZOJ4415 [SHOI2013] 发牌

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4415 Description 假设一开始,荷官拿出了一副新牌,这副牌有N张不同的牌,编号依次为1到N.由于是新牌,所以牌是按照顺序排好的,从牌库顶开始,依次为1, 2,……直到N,N号牌在牌库底.为了发完所有的牌,荷官会进行N次发牌操作,在第i次发牌之前,他会连续进行R_i次销牌操作,R_i由输入给定.请问最后玩家拿到这副牌的顺序是什么样的? 举个例子,假设N = 4,则一开始的时候,牌

[BZOJ 4418][Shoi2013]扇形面积并(树状数组+二分)

Description 给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖. Solution 打开发现是计算几何还以为是看错题号了QwQ 其实就是遇到一条开始的边+1,遇到一条结束的边-1,a1>a2的话就再加上一个完整的圆 计算每一部分只需要找到第cnt-k+1大的半径,在树状数组上二分就好了 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #inc

待 题表

题表 达哥终极杂题表Bzoj2839 hdu6021 Codeforces 804DBzoj2248 hdu5575 Codeforces 786CBzoj2013 bzoj2676 Codeforces 803CBzoj2386 bzoj3782 Codeforces 813DBzoj2699 cogs1667 Codeforces 814DBzoj4798 bzoj2064 Codeforces 814EBzoj4639 bzoj3505 Codeforces 815ABzoj4417 bz

BZOJ 4416 【SHOI2013】 阶乘字符串

题目链接:阶乘字符串 又是一道不会做的题--看了题解后我被吓傻了-- 首先我们可以有一个显然的\(O(2^nn)\)的做法.我们先预处理出\(g_{i,j}\)表示字符串中\(i\)号位置开始第一个\(j\)字符出现在什么位置.然后就可以用\(f_S\)表示使得\(S\)集合内字符的排列全都出现的最小长度,然后就可以递推了. 然后--翻了一波题解,发现当\(n>21\)的时候无解--听说合法的串长应该是\(n^2\)级别的,所以当\(n>21\)的时候就无解了--然后就可以\(O(2^nn)\

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

为何感觉SHOI的题好水...又是一道SB题 从左到右枚举每一个区间,遇到一个扇形的左区间就+1,遇到右区间就-1,然后再树状数组上2分答案,还是不会码log的..SHOI2013似乎还有一道题发牌也是类似的维护方法.. #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<vector>

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample Input 4 7558588 9653114 6514903 445