Made by 退役的OIer

第一次写博客,写得不好 or 不清楚的可以 在下方留言,我会尽量改进的!


好啦~~~回到正题,题面见传送门

【问题描述】

  采药人最近在认真切题,但回旋的转盘时常在眼前浮现,旧日的美好时光总把他带回那个无忧无虑的押忍战斗应援团的时代。于是他在切题的时候也按照这样的规则以怀念旧时光。
  规则是这样的:采药人手头有 n 道题,他会将其按 1 到 n 的顺序绕成一个环,他会从 1开始按照 1 到 n 顺序每隔 p 道没写过的写一题,直到这些题都写完了。他想知道这些题中第 k 个被他切掉的题是第几题?
  如有 7 道题,采药人每隔 3 道写一题。那么他写题的顺序是 3 6 2 7 5 1 4。

【输入格式】

第一行,一个整数 t,表示数据组数
接下来 t 行,每行三个正整数 n,p,k,意义如题目所述

【输出格式】

t 行,每行一个整数,表示答案

【输入输出样例】

rule.in
1
7 3 7
rule.out
4

【数据规模】

对于 20%,k<=n<=1000,p<=100
对于 40%,k<=n<=10000,p<=1000
对于另外 20%,k<=n<=1000000000,p<=2
对于 100%,t<=10,k<=n<=10^14,p<=10000

solution:

  首先我们可以看出这就是Joseph问题(如果不会请移步至Joseph问题

最最基础的算法就是模拟啦~~~

数p道题就切掉当前这个,重复k次,我们当然可以使用循环链表模拟这个过程(很形象的)

部分代码如下:

void pre()
{
FOR(i,,n)
{
l[i]=(i==)?n:i-;
r[i]=(i==n)?:i+;
}
return;
}
void del(int x)//在链表中删除x(即把x两边的连起来)
{
r[l[x]]=r[x];
l[r[x]]=l[x];
return;
}
//在main中
int pos=n;
while(k-->)
{
FOR(i,,p) pos=r[pos];
del(pos);
}
printf("%d",pos);

哈哈,是不是很简单?

然而,仔细一想,整个算法时间复杂度为O(pk)

emmm....显然炸得裂开

我们急需寻找一个更为高效的算法

递推!

我们发现,一个队列进行一次切题操作后,长度会减小1,而队列开头到切掉的题的下一个

即可以从此处重新编号1~(n-1),相当于对当前队列编号整体减p

(自己推一推,模拟  切 一 道 题  的过程)

假设f[i][j]为队列长度为 i 时 , 切掉的第 j 道题的编号

则有以下递推式:

初态即

又可以发现,f数组没有必要,只用一个变量pos即可

那么代码就出来了:

//在main中
int pos=(p-)%(n-k+)+;
FOR(i,n-k+,n)
{
pos=(pos+p-)%i+;
}
printf("%d",pos);

分析一波发现,算法时间复杂度降到了O(k)

wow~~~优(yiu)秀(xiu)

欣喜地看看数据范围, ?@#(*%&@#!

k<=n<=10^14

这说明我们需要更~~~~~~~~高效的算法!

???(仔细想想怎么优化,想完再往下看)




就一个小优化即可:乘法加速

用乘法加速加法运算(是不是很简单)

(不对呀,这里有取模,怎么加速???)

很容易发现,取模并不是每次都有改变,就是说取模把加法分成了若干小段,每个小段中pos是连加的

每次 i 增加 1 时, pos 增加 p(是不是很像追及问题?)

那么每段中, i 就会增加 tmp, 其中

这样就很好办了~~~

再就不多说了,见完整代码

#include<cstdio>
#define ll long long
#define rll register ll
ll n,p,k,len,pos;
int T;
int main()
{
scanf("%d",&T);
while(T-->)
{
scanf("%lld%lld%lld",&n,&p,&k);
if(p==) printf("%lld\n",k);//注意特判p==1的时候
else
{
len=n-k+;pos=(p-)%len+;
for(rll tmp();len+tmp<=n;tmp=(len-pos)/(p-)+)
pos=(pos+tmp*p-)%(len+=tmp)+;
printf("%lld\n",(pos+(n-len)*p-)%n+);
}
}
return ;
}

是不是很简单?

复杂度也很简单,O(T * F(k) )(其中F(k)为关于k的函数,值很小,可近似为log(k))

愉快地  切 一 道 题  啦~~~


最后,

感谢   P.Y.Y  提供的官方题解平台~~~

感谢各位   巨佬&&神犇   的支持与鼓励~~~

可别忘了指正,转发与推荐哟~

(链接:https://www.cnblogs.com/HSY-2019/p/12367741.html)

【题解】 2月19日 厦门双十中学NOIP2014模拟D2 T1 采药人的切题规则的更多相关文章

  1. 【题解】 2月19日 厦门双十中学NOIP2014模拟D2 T2 采药人接水果

    [问题描述] 采药人虽然 AFO(SU),但他在闲暇的时候还是可以玩一玩接水果(cat)的.但他渐渐发现 cat 好像有点太弱智.于是他不想浪费他的智商,于是决定写一个程序帮他玩. cat 是这样玩的 ...

  2. 【Usaco 2009 Gold】JZOJ2020年9月19日提高B组T4 过路费

    [Usaco 2009 Gold]JZOJ2020年9月19日提高B组T4 过路费 题目 Description 跟所有人一样,农夫约翰以着宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生财之 ...

  3. 【Usaco 2009 Gold】JZOJ2020年9月19日提高B组T3 头晕的奶牛

    [Usaco 2009 Gold]JZOJ2020年9月19日提高B组T3 头晕的奶牛 题目 Description 奶牛们发现,在农场里面赛跑是很有趣的一件事.可是她们一旦在农场里面不断地转圈,就会 ...

  4. 【Usaco 2009 Gold 】JZOJ2020年9月19日提高B组T2 电视游戏问题

    [Usaco 2009 Gold ]JZOJ2020年9月19日提高B组T2 电视游戏问题 题目 Description 农夫约翰的奶牛们游戏成瘾!本来FJ是想要按照陶叫兽的做法拿她们去电击戒瘾的,可 ...

  5. 【Usaco 2009 Silver】JZOJ2020年9月19日提高B组T1 音乐节拍

    [Usaco 2009 Silver]JZOJ2020年9月19日提高B组T1 音乐节拍 题目 Description FJ准备教他的奶牛弹奏一首歌曲,歌曲由N(1<=N<=50,000) ...

  6. Python array,list,dataframe索引切片操作 2016年07月19日——智浪文档

    array,list,dataframe索引切片操作 2016年07月19日——智浪文档 list,一维,二维array,datafrme,loc.iloc.ix的简单探讨 Numpy数组的索引和切片 ...

  7. 2016年12月19日 星期一 --出埃及记 Exodus 21:14

    2016年12月19日 星期一 --出埃及记 Exodus 21:14 But if a man schemes and kills another man deliberately, take hi ...

  8. 2016年11月19日 星期六 --出埃及记 Exodus 20:10

    2016年11月19日 星期六 --出埃及记 Exodus 20:10 but the seventh day is a Sabbath to the LORD your God. On it you ...

  9. 2016年10月19日 星期三 --出埃及记 Exodus 19:3

    2016年10月19日 星期三 --出埃及记 Exodus 19:3 Then Moses went up to God, and the LORD called to him from the mo ...

随机推荐

  1. spring.net 基础 1

    Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序 1: 在2004年初,Martin Fowler曾经问他网站的读者:当我们谈到控制反转时,"问题是, ...

  2. IDEA工具java开发之 常用窗口

    ◆project窗口  ◆structure窗口  ◆todo窗口  ◆favorites窗口  ◆termimal窗口 此窗口默认打开的时cmd,所以才这里可以操作任何cmd可以操作的内容, 一般次 ...

  3. latex2e

    classs and packages 这一节介绍新的latex文档结构, 以及新的文件类型: classs and packages 类和包是什么? lext 2.09和latex2e的主要差别就在 ...

  4. Qt Installer Framework翻译(7-5)

    操作 这些操作由组件和控制脚本准备,并由安装程序执行. 注意:操作是通过线程执行的. 在内部,每个操作都有一个DO步骤,包含有关安装程序的说明,以及一个UNDO步骤,包含有关卸载程序的说明. 操作总结 ...

  5. [校内训练19_09_02]A

    题意 给出N 个形如$f_i(x) = a_i x^2 + b_i x $的二次函数. 有Q 次询问,每次给出一个x,询问$max{\{f_i(x)\}}$.$N,Q \leq 5*10^5$. 思考 ...

  6. [ZJOI2008]树的统计(树链剖分)

    [ZJOI2008]树的统计(luogu) Description 一棵树上有 n 个节点,编号分别为 1 到 n,每个节点都有一个权值 w.我们将以下面的形式来要求你对这棵树完成一些操作: I. C ...

  7. Liunx(centos8)下的yum的基本用法和实例

    yum 命令 Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从指定的 ...

  8. 安装pycharm后设置idle为默认打开方式(idle.bat)图标“变异”为未知bug

    这个虽不影响使用,但是对着一个白色的框框,这体验真的是不符合强迫症的风格啊~~~注册表,重装,......解决方案多多种,但是经过大神推荐,有一个很好用的小工具, 下载地址:Default Progr ...

  9. Day3-Python3基础-函数

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 1.函数的定义 定义: 函数是指将一组语句的集 ...

  10. 《 Java 编程思想》CH05 初始化与清理

    < Java 编程思想>CH05 初始化与清理 用构造器确保初始化 在 Java 中,通过提供构造器,类的设计者可确保每个对象都会得到初始化.Java 会保证初始化的进行.构造器采用与类相 ...