预备知识:反素数解析

思路:有了反素数的解法之后就是线段树的事了。

我们可以用线段树来维护哪些人被淘汰,哪些人没被淘汰,被淘汰的人的位置,没被淘汰的人的位置。

我们可以把所有人表示为一个[1,n]的区间,没被淘汰的人权值为1,那么通过线段树维护区间和,就可以知道没被淘汰人的分布情况,tree[root].value就是总人数。因为线段树的二分性质,如果淘汰的人在第x个位置,那么我们可以找到区间和为x的位置来得到这个人的位置,把这个位置的权值更新为0,然后更新线段树,就可以表示这个人被淘汰,总人数也是减去1,就可以表示游戏中还剩多少人。

假设这个被淘汰的人位置是inx,下一个淘汰的人位于他的左(右)第A个,我们可以mod = A%(剩余人数),然后我们可以得到inx左边(L)和右边的人数(R),然后根据mod和A的正负号来确定下一个人的位置。

 #include <iostream>
#include <cmath>
#include <cstdio> #define ll long long using namespace std; const int N = 5e5+;
struct Info{
char name[];
int turn;
}p[N];
struct node{
int l,r,value;
int mid(){ return (l+r) >> ; }
}tree[N << ];
int c[N];
int n, s, ss, inx;
int pr[] = {,,,,,,,,,};
int Max,num; void dfs(int inx, int v, int cnt, int pw){
for(int i = ; i <= pw; ++i){
if((ll)v * pr[inx] > (ll)n){
if(Max < cnt * i){
Max = cnt * i;
num = v; }else if(cnt * i == Max) num = min(num, v);
break;
}
else dfs(inx + , v *= pr[inx], cnt * (i + ), i); }
} //反素数模板
void AntPrime(){
Max = ;
dfs(, , , );
} void build_tree(int rt, int L, int R){
tree[rt].l = L; tree[rt].r = R;
if(L == R){
if(L == s) inx = rt;
tree[rt].value = ;
return;
}
int mid = tree[rt].mid();
int lson = rt << ;
int rson = rt << | ;
build_tree(lson, L, mid);
build_tree(rson,mid + , R);
tree[rt].value = tree[lson].value + tree[rson].value;
} void update(int x){
while(x != ){
--tree[x].value;
x >>= ;
}
} void search(int tot,int rt){
//找到位置
if(tree[rt].l == tree[rt].r){
ss = tree[rt].l; //原始队列的位置
inx = rt; //线段树的位置,方便更新
return;
}
int lson = rt << ;
int rson = rt << | ;
if(tree[lson].value >= tot) search(tot, lson);
else search(tot - tree[lson].value, rson);
} void solve(){
while(~scanf("%d%d", &n, &s)){
build_tree(,,n);
AntPrime();//得到反素数和它的约数个数
for(int i = ; i <= n; ++i){
scanf("%s%d", p[i].name, &p[i].turn);
}
int cnt = ;
int remain = n;
//s 淘汰队列人的位置
//ss 原始队列人的位置
ss = s;
while(++cnt != num){
update(inx);//更新线段树
int turn = abs((double)p[ss].turn);
turn %= (remain - );
if(!turn) turn = remain - ;
if(p[ss].turn > ){
int r = remain - s;
if(r >= turn) s = s + turn - ;
else s = turn - r;
}else{
int l = s - ;
if(l >= turn) s = l - turn + ;
else s = (remain - ) - (turn - l) + ;
}
// cout << "position is " << ss << endl;
// cout << "jumped out people " << p[ss].name << endl;
search(s, );
--remain;
}
printf("%s %d\n", p[ss].name, Max);
}
} int main(){ solve(); return ;
}

Who Gets the Most Candies? POJ - 2886(线段树单点更新+区间查询+反素数)的更多相关文章

  1. POJ 2886 线段树单点更新

    转载自:http://blog.csdn.net/sdj222555/article/details/6878651 反素数拓展参照:http://blog.csdn.net/ACdreamers/a ...

  2. HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)

    HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...

  3. NYOJ-568/1012//UVA-12299RMQ with Shifts,线段树单点更新+区间查询

    RMQ with Shifts 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 ->  Link1  <- -> Link2  <- 以上两题题意是一样 ...

  4. poj 2886 线段树的更新+反素数

    Who Gets the Most Candies? Time Limit: 5000 MS Memory Limit: 0 KB 64-bit integer IO format: %I64d , ...

  5. poj 2828(线段树单点更新)

    Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 18561   Accepted: 9209 Desc ...

  6. POJ 2828 (线段树 单点更新) Buy Tickets

    倒着插,倒着插,这道题是倒着插! 想一下如果 Posi 里面有若干个0,那么排在最前面的一定是最后一个0. 从后往前看,对于第i个数,就应该插在第Posi + 1个空位上,所以用线段树来维护区间空位的 ...

  7. HDU 1166敌兵布阵+NOJv2 1025: Hkhv love spent money(线段树单点更新区间查询)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  8. HDU1166(线段树单点更新区间查询)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. HDU 1754.I Hate It-结构体版线段树(单点更新+区间查询最值)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

随机推荐

  1. maven工程根项目运行ok但是子项目就报错的解决办法

    正常启动没错 项目出现问题 maven工程根项目运行ok但是子项目就报错 报错信息是xxxx没有创建 解决办法 原来是子项目的依赖少了  没有配置1.8  所以会出现莫明其妙的bug

  2. 模型压缩之Channel Pruning

    论文地址 channel pruning是指给定一个CNN模型,去掉卷积层的某几个输入channel以及相应的卷积核, 并最小化裁剪channel后与原始输出的误差. 可以分两步来解决: channe ...

  3. 在 React Native 中使用 moment.js 無法載入語系檔案

    moment.js 是很常見的日期時間 library,友善的 API 與極佳的執行效率是它的兩大賣點.例如 (new Date()).getFullYear(),如果使用 moment.js 我可以 ...

  4. oracle监控参数

    Sar –u 检查CPU的繁忙程度列说明Usr用户模式下cpu运行所占的百分比Sys系统模式下cpu运行所占的百分比Wio因为有进程等待块I/O而使cpu处于闲置状态所占百分比IdleCpu为闲置状态 ...

  5. 5G时代,会有什么奇葩事儿?

    ​ 在3GPP RAN第187次会议关于5G短码方案的讨论中,中国华为推荐的PolarCode方案获得认可,成为5G控制信道eMBB场景编码的最终解决方案.坦白讲,笔者在读这个新闻的时候,手里备着一本 ...

  6. 使用pandas筛选出指定列值所对应的行

    在pandas中怎么样实现类似mysql查找语句的功能: select * from table where column_name = some_value; pandas中获取数据的有以下几种方法 ...

  7. C++走向远洋——55(项目一3、分数类的重载、>>

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  8. Java入门教程十一(异常处理)

    在程序设计和运行的过程中,发生错误是不可避免的.尽管 Java 语言的设计从根本上提供了便于写出整洁.安全代码的方法,并且程序员也尽量地减少错误的产生,但是使程序被迫停止的错误的存在仍然不可避免.为此 ...

  9. go语言指南之切片练习

    题目: 实现 Pic.它应当返回一个长度为 dy 的切片,其中每个元素是一个长度为 dx,元素类型为 uint8 的切片.当你运行此程序时,它会将每个整数解释为灰度值(好吧,其实是蓝度值)并显示它所对 ...

  10. 8421BCD转余3码Verilog HDL的设计(1)

    近期阅读Verilog HDL高级数字设计(第二版)中,遇到了串行比特流BCD码转余3码转换器的设计,比较独特的是: (1)该转换器的输入为1位串行比特流,输出也为1位串行比特流. BCD码与余三码的 ...