预备知识:反素数解析

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

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

我们可以把所有人表示为一个[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. 由生到死10个月!做App中的“二”有多难

    十月,原本是怀胎过程的喜悦时光,但这段个时光,如今却是绝大多数App从生到死的所有时间.在App市场表面形式一片大好,彻底主宰我们生活.工作.娱乐的当下,绝大多数用户只是在App海洋中只取一瓢饮,其他 ...

  2. 杂记:Linux下gcc升级

    公司要求,需要在CentOS6.5系统下进行一些测试.因为编写的测试程序中使用了一些C++11之后新增的特性,而CentOS6.5中安装的gcc版本为4.4.7,并不支持C++11,所以需要对gcc进 ...

  3. 每天一个linux命令(15)-tail

    tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不断刷新, ...

  4. 从未来看 C#

    前言 如今 C# 虽然发展到了 8.0 版本,引入了诸多的函数式特性,但其实在 C# 未来的规划当中,还有很多足以大规模影响现有 C# 代码结构和组成的特性,本文中将会对就重要的特性进行介绍,并用代码 ...

  5. python爬虫-提取网页数据的三种武器

    常用的提取网页数据的工具有三种xpath.css选择器.正则表达式 1.xpath 1.1在python中使用xpath必须要下载lxml模块: lxml官方文档 :https://lxml.de/i ...

  6. python画一颗拳头大的💗

    用上turtle库后,各种画,今天画个拳头大的爱心@.@. 下面贴下代码: # -*- coding: utf-8 -*- # Nola import pygame import time impor ...

  7. AE脚本:把SubRip/SRT/TXT/VTT字幕导入到AE

    脚本介绍 如果您需要在视频中嵌入字幕以进行网络或磁带传送,那么这个脚本则非常有用.可以将SubRip/SRT/TXT/VTT字幕格式文件通过 pt_ImportSubtitles脚本直接加载到AE软件 ...

  8. 阿里云ECS开放批量创建实例接口,实现弹性资源的创建

    摘要: 为了更方便的实现弹性的资源创建,方便用户一次运行多台ECS按量实例来完成应用的开发和部署,阿里云开放了ECS的批量创建实例接口RunInstances,可以单次最多创建100台实例,避免重复调 ...

  9. JZOJ 5230. 【NOIP2017模拟A组模拟8.5】队伍统计

    5230. [NOIP2017模拟A组模拟8.5]队伍统计 (File IO): input:count.in output:count.out Time Limits: 1500 ms Memory ...

  10. Ubuntu16.04下安装python3.6.4详细步骤

    记录一下: Ubuntu16.04自带的python版本为python2.7和python3.5,现在想要安装python3.6.4,注意:系统自带的python版本别删除 步骤: # 官网下载安装包 ...