poj2886(线段树求序列第k小)
题目链接:https://vjudge.net/problem/POJ-2886
题意:n个人围成一个圈,每个人有姓名s和权值val两个属性,第一轮序号为k的人退出,并根据其val指定下一个人,val为正即其右第val个人,val为负及其左第val个人。求第p个出局的人的姓名,其中p的约数最多,并输出约数的数量。
思路:首先是数学问题,可通过唯一分解定理或筛法打表计算出n个人时第几个出局的人的约数最多f1[n],和约数的数量f2[n],数据很小,不打表的话会超时。然后进行f1[n]次循环,每次找出当前序列中第k小的人。利用线段树来实现,线段树的结点属性sum表示该区间剩余数的个数,每次更新时都要减一。最后就是确定每次的k值。
if(tmp>0)
k=((k-1+tmp-1)%Mod+Mod)%Mod+1;
else
k=((k+tmp-1)%Mod+Mod)%Mod+1;
tmp>0时,因为要将k删除,那么k的下一位仍是第k小,所以要减1,后面的减一再加一是避免出现0。tmp<0时,k的下一位是第k-1小,就不用减1了。自己举个例子模拟一下就懂了。
AC代码:
#include<cstdio>
using namespace std;
const int maxn=; struct node1{
char s[];
int val;
}boy[maxn]; struct node2{
int l,r,sum;
}tr[maxn<<]; int f1[]={,,,,,,,,,,,,,,,
,,,,,,,,
,,,,,,,
,,,,,,};
int f2[]={,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,
,,,,,};
int n,k; void build(int v,int l,int r){
tr[v].l=l,tr[v].r=r,tr[v].sum=r-l+;
if(l==r) return;
int mid=(l+r)>>;
build(v<<,l,mid);
build(v<<|,mid+,r);
} int update(int v,int k){
--tr[v].sum;
if(tr[v].l==tr[v].r)
return tr[v].r;
if(tr[v<<].sum>=k) return update(v<<,k);
else return update(v<<|,k-tr[v<<].sum);
} int main(){
while(~scanf("%d%d",&n,&k)){
for(int i=;i<=n;++i)
scanf("%s%d",boy[i].s,&boy[i].val);
int num,nump,nw=,Mod=n,pos;
for(int i=;i<=;++i)
if(n>=f1[i]&&n<f1[i+]){
num=f1[i];
nump=f2[i];
break;
}
build(,,n);
while(){
--Mod;
pos=update(,k);
if(++nw==num) break;
int tmp=boy[pos].val;
if(tmp>)
k=((k-+tmp-)%Mod+Mod)%Mod+;
else
k=((k+tmp-)%Mod+Mod)%Mod+;
}
printf("%s %d\n",boy[pos].s,nump);
}
return ;
}
poj2886(线段树求序列第k小)的更多相关文章
- poj2182(线段树求序列第k小)
题目链接:https://vjudge.net/problem/POJ-2182 题意:有n头牛,从1..n编号,乱序排成一列,给出第2..n个牛其前面有多少比它编号小的个数,记为a[i],求该序列的 ...
- poj2828(线段树查找序列第k小的值)
题目链接:https://vjudge.net/problem/POJ-2828 题意:有n个人,依次给出这n个人进入队列时前面有多少人p[i],和它的权值v[i],求最终队列的权值序列. 思路:基本 ...
- 线段树维护区间前k小
线段树维护区间前k小 $ solution: $ 觉得超级钢琴太麻烦?在这里线段树提供一条龙服务 . 咳咳,开始讲正题!这道题我们有一个和超级钢琴复杂度一样 $ ~O(~\sum x\times lo ...
- 【学习笔记】浅析平衡树套线段树 & 带插入区间K小值
常见的树套树 一般来说,在嵌套数据结构中,线段树多被作为外层结构使用. 但线段树毕竟是 静态 的结构,导致了一些不便. 下面是一个难以维护的例子: 带插入区间 \(k\) 小值问题 来源:Luogu ...
- SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)
COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...
- SPOJ 10628 Count on a tree(Tarjan离线 | RMQ-ST在线求LCA+主席树求树上第K小)
COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...
- HDOJ题目4417 Super Mario(划分树求区间比k小的个数+二分)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- 主席树--动态区间第k小
主席树--动态区间第\(k\)小 模板题在这里洛谷2617. 先对几个问题做一个总结: 阅读本文需要有主席树的基础,也就是通过区间kth的模板题. 静态整体kth: sort一下找第k小,时间复杂度\ ...
- 2016年湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)
原题链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 Description Bobo has a balanced parenthes ...
随机推荐
- close_wait状态和time_wait状态(TCP连接)
1.CLOSE_WAIT的简单解决方案 不久前,我的Socket Client程序遇到了一个非常尴尬的错误.它本来应该在一个socket长连接上持续不断地向服务器发送数据,如果socket连接断开,那 ...
- python 多线程threading的学习一
1. import threading #引入线程模块 2 申明实例 t = threading.Thread(target = fun, args = (,)) 说明:参数target 是要运行的 ...
- nginx1.14.0版本高可用——keepalived双机热备
nginx不支持主从,所以我们需要使用keepalive支持高可用. keepalived重要知识点 在局域网内,每个主机上各安装一个keepalived,注意关闭防火墙firewalld,然后设定一 ...
- String.format()的使用
参考文章: https://www.cnblogs.com/Dhouse/p/7776780.html 其中System.out.printf()的用法可参考:https://blog.csdn.ne ...
- navicat 导入execl失败
在使用navicat导入execl是遇到了如下图的错误 在更换多个版本的navicat后问题依然如故. 解决办法; 1.打开需要导入的execl 2.安装一个AccessDatabaseEngine_ ...
- Cesium学习网址
不错的案例介绍: 根据地形瓦片直接绘制高程.坡度及等高线 同一场景下显示两个不同的瓦片图层 https://cloud.tencent.com/developer/article/1113355 绘制 ...
- Oracle创建用户、授权、规则
---用户登录命令--管理员登录conn sys/oracle as sysdba;--创建用户方案必须是管理员权限--创建用户命令 create user useranme identifild b ...
- pil库的介绍与应用
PIL (Python Image Library) 库是Python 语言的一个第三方库,PIL库支持图像存储.显示和处理,能够处理几乎所有格式的图片. 一.PIL库简介 1. PIL库主要有2个方 ...
- 获取的是 string 类型的字段,直接输出 数字 或者 需要的第几行
Freight = driver.find_element_by_xpath("//tbody/tr/td[6]").text print(type(Freight)) # 这里输 ...
- idea中git常见使用场景
工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下: 假设小组中有两个人,组长小张,组员小袁 场景一:小张创建项目并提交到远程Git仓库 场景二:小袁从远程Git仓库上获取项目源码 场景三:小 ...