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 ...
随机推荐
- Busybox镜像
使用docker多少还是要知道一些Busybox的知识,下面转载自https://blog.csdn.net/chengqiuming/article/details/79313539 一 简介 Bu ...
- canvas一些属性
lineTo(x,y) 定义线条结束坐标 moveTo(x,y) 定义线条开始坐标 ctx.stroke();绘制空心图形 ctx.fill();填充图形 把当前路径环绕起来的区域进行填充 ctx.f ...
- 基于STM8的GPIO操作---STM8-第一章
1. 综诉 也许单片机在你看来是一件不太容易的事,但据我所知,单片机,无非就是控制它的GPIO口,所以可以看出,学会如何操作控制GPIO口对使用单片机来说是很重要的一件事. 在装载STM8的单片机中, ...
- HTML如何实现斜体字
HTML实现斜体字的标签为<i>标签,用来实现字体倾斜,写法如下: 字体斜体:<i>内容</i> 案例:正常 斜体 当文字加入i标签以后字体就会成为斜体
- C++ 64位操作系统调用 RegOpenKey() 读取注册表,返回 2, ERROR_FILE_NOT_FOUND
环境:64位操作系统, VS2017 首先在命令行执行 REG ADD HKLM\Software\seastarsun /v serial /t REG_SZ /d 58ae4cb077a4e1 在 ...
- 负载均衡器技术Nginx和F5的优缺点对比
负载均衡器技术Nginx和F5的优缺点对比 博客分类: 应用服务 F5nginx 对于数据流量过大的网络中,往往单一设备无法承担,需要多台设备进行数据分流,而负载均衡器就是用来将数据分流到多台设备的 ...
- leetcode《按递增顺序显示卡牌》
题目描述: 牌组中的每张卡牌都对应有一个唯一的整数.你可以按你想要的顺序对这套卡片进行排序. 最初,这些卡牌在牌组里是正面朝下的(即,未显示状态). 现在,重复执行以下步骤,直到显示所有卡牌为止: 从 ...
- Python 有道翻译 爬虫 有道翻译API 突破有道翻译反爬虫机制
py2.7 #coding: utf-8 import time import random import hashlib import requests while(1): url = 'http: ...
- 网络通信协议tcp,udp区别
1 网络通信协议 Tcp udp的区别 重点(*****) Tcp三次握手四次挥手(******) udp客户端多人聊天 import socket udp_client = socket.socke ...
- 接口测试总结分享(http与rpc)
接口测试是测试系统组件间接口的一种测试.接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点.测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等. 一.了 ...