题目

题目大意

给你一个由整点组成的矩形,坐标绝对值范围小于等于\(n\),你在\((0,0)\),一开始面向\((1,0)\),每次转到后面第\(k\)个你能看到的点,然后将这条线上的点全部标记删除。

问最后一个被标记删除的点的坐标。


正解

先吐槽一句,原来删除的点是一条线上的,而不是一个点……

害得我以为是一道神题……更可恨的是,我看不出我的暴力有什么错!

既然一次删除的点是在一条线上的,那不妨将整条线上的东西看成一个点。

那就变成了一个约瑟夫问题(也就是猴子选大王)。

共有\(8\sum_{i=1}^{n}\phi(i)\)个(原图分成\(8\)个三角形,减去对角线被算\(4\)次,加上垂直和水平方向\(4\)个)

设现在有\(n\)个,则将第\(k\)个删除之后,就变成了\(n-1\)个的问题。所以可以通过递归来求。设\(f_i\)表示\(i\)个人在搞完之后最后一个留下的人是谁(编号从\(0\)开始)

显然\(f_i=(f_{i-1}+k)\mod i\)

然而这个东西似乎会爆炸,因为总数是很多的。

考虑如何快速计算这玩意儿。现在,最主要的瓶颈就是取模操作。

由于不一定每次都会大于模数,所以考虑加几次\(k\)之后取一次模。

假设现在有\(n\)个,设至少增加\(x\)个之后要取一次模。

于是就有了不等式:\(f_n+kx\geq n+x\),解得\(x\geq \frac{n-f_n}{k-1}\)

(当然不要忘了上取整)

这样算会快很多,但是时间看起来似乎不是很好算。

计算一下时间:当\(n\leq k\)时,每次\(n\)只能变成\(n+1\),这一部分时间为\(O(k)\).

当\(n>k\)时,每次相当于加上\(\frac{n}{k}\)左右。

尽管看起来并不是很靠谱,但实际上,某个\(f_n+k\)之后超过了\(n+1\),于是取模,\(f_{n+1}\)不会超过\(k\)。所以当\(n\)远远大于\(k\)时,每次\(f_n\)和\(n\)相差比较大,它们的差就可以近似地认为是\(n\)。(或者说约等于于加上\(\frac{n-k}{k}\),有了个\(-1\)的常数,就省去了)

加上\(\frac{n}{k}\)相当于乘\(\frac{k+1}{k}\)。

于是这一部分时间大概为\(O(\log_\frac{k+1}{k}n)\)

是对数级别时间复杂度,似乎很快的样子。如果用个换底公式,把\(\frac{1}{\lg\frac{k+1}{k}}\)的常数给省掉,那么看起来是\(O(\lg n)\)的时间复杂度呢,似乎很优秀。但是这个常数实际上不能省!用计算器计算一下,这个常数大概为\(230260\)(这里的\(\lg\)是指\(\log_{10}\),不是\(\log_2\),计算器里面没有直接提供\(\log_2\)这种东西,所以干脆直接用\(\log_{10}了\))。

不过还好,时间还是过得去……

接下来变成另一个问题:寻找排名第几项的位置。

首先,找到这个位置在哪个象限。接下来只讨论第一象限的,其它的在此基础上旋转一下就好了。

很容易想到二分。假设我们二分出了一个分数\(\frac{b}{a}\)

现在我们要求再斜率为\(\frac{b}{a}\)这条直线一下的点数。

具体来说,就是这个式子:\(\sum_{i=1}^{n}\sum_{j=1}^{n}[gcd(i,j)=1]*[\frac{j}{i}<\frac{b}{a}]\)

这个式子可以反演(说实在的,我对反演非常不熟悉)

有个比较重要的性质:\(\sum_{d|n}\mu(d)=[n=1]\)

\[\sum_{i=1}^{n}\sum_{j=1}^{n}\sum_{d|gcd(i,j)}\mu(d)*[\frac{j}{i}<\frac{b}{a}]
\\ =\sum_{i=1}^n\sum_{d|i}\mu(d)\sum_{d|j,j\leq n}[j<\frac{bi}{a}]
\\ =\sum_{i=1}^n\sum_{d|i}\mu(d)\min(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{bi}{ad}\rfloor)
\\ =\sum_{d=1}^n\mu(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\min(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{bi}{a}\rfloor)\]

有了这条式子,就可以在\(O(n\ln n)\)的时间内判断了。

至于如何二分,题解有种比较容易理解的暴力用小数来逼近分数的方法,Cold_Chair大爷有个\(Stern-Brocot Tree\)上二分的强大做法(由于节点的深度可能比较深,但拐角处是\(\lg\)级别的,所以还要二分一下在某个方向上走多长距离。而且求答案的时候,还用到了整除分块)


代码(未AC)

最近没有AC的题目很多,代码都摆在这里,以后也不一定会去调试了……

话说程序里我用的是小数来逼近分数的方法,不过为了追求常数,我把小数变成了分数的形式。当然,这个分数的分母都是\(2\)的幂。

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <climits>
#define N 100000
#define ll long long
int n,K;
int p[N+10],np;
bool inp[N+10];
int phi[N+10],mu[N+10];
ll calc(ll tar){
// return (K+calc(n-1))%n;
ll n=1,fn=0;
do{
ll x=(n-fn -1)/(K-1) +1;
if (tar<n+x)
return fn+K*(tar-n);
n=n+x;
fn=(fn+K*x)%n;
}
while (1);
}
ll below(ll a,ll b){
ll res=0;
for (int d=1;d<=n;++d){
ll s=0,n_d=n/d;
for (int i=1;i*d<=n;++i)
s+=min(b*i/a,n_d);
res+=s*mu[d];
}
return res;
}
int main(){
// freopen("in.txt","r",stdin);
freopen("garden.in","r",stdin);
freopen("garden.out","w",stdout);
scanf("%d%d",&n,&K);
if (K==1){
printf("%d %d\n",n,-1);
return 0;
}
phi[1]=1,mu[1]=1;
for (int i=2;i<=n;++i){
if (!inp[i]){
p[++np]=i;
phi[i]=i-1;
mu[i]=-1;
}
for (int j=1;j<=np && i*p[j]<=n;++j){
inp[i*p[j]]=1;
if (i%p[j]==0){
phi[i*p[j]]=phi[i]*p[j];
break;
}
phi[i*p[j]]=phi[i]*(p[j]-1);
mu[i*p[j]]=mu[i]*mu[p[j]];
}
}
ll one=1,all=0;
for (int i=2;i<=n;++i)
one+=phi[i]*2;
all=one*4+4;
ll num=calc(all);
if (num==0)
printf("%d %d\n",n,0);
else if (num==one+1)
printf("%d %d\n",0,n);
else if (num==2*one+2)
printf("%d %d\n",-n,0);
else if (num==3*one+3)
printf("%d %d\n",0,-n);
else{
int rank=num%(one+1);
ll l=0,r=n,d=0;
while (d<30){
ll mid=l+r;
if (below(1<<d+1,mid)<rank)
l=mid,r<<=1;
else
r=mid,l<<=1;
d++;
}
// printf("%lf\n",(double)r/(1ll<<d));
int x,y;
long double v=(long double)r/(1ll<<d),tmp=2e9;
for (ll i=n;i>=1;--i){
ll j=r*i/(1ll<<d)/*(ll)(v*i)*/;
if (v-double(j)/i<tmp){
tmp=v-double(j)/i;
y=j;
x=i;
}
}
if (num<one+1)
printf("%d %d\n",x,y);
else if (num<2*one+2)
printf("%d %d\n",-y,x);
else if (num<3*one+3)
printf("%d %d\n",-x,-y);
else
printf("%d %d\n",y,-x);
}
return 0;
}

总结

审题是关键。

反演及其不熟练,需要找时间来提升。(实际上我似乎没有AC过一道反演的题目)

6383. 【NOIP2019模拟2019.10.07】果实摘取的更多相关文章

  1. 【NOIP2019模拟2019.10.07】果实摘取 (约瑟夫环、Mobius反演、类欧、Stern-Brocot Tree)

    Description: 小 D 的家门口有一片果树林,果树上果实成熟了,小 D 想要摘下它们. 为了便于描述问题,我们假设小 D 的家在二维平面上的 (0, 0) 点,所有坐标范围的绝对值不超过 N ...

  2. 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题目描述 题解 随便bb 详细题解见 https://www.cnblogs.com/coldchair/p/11624979.html https://blog.csdn.net/alan_cty/ ...

  3. 6392. 【NOIP2019模拟2019.10.26】僵尸

    题目描述 题解 吼题但题解怎么这么迷 考虑一种和题解不同的做法(理解) 先把僵尸离散化,h相同的钦(ying)点一个大小 (可以发现这样每种情况只会被算正好一次) 计算完全被占领的方案,然后1-方案/ ...

  4. 6389. 【NOIP2019模拟2019.10.26】小w学图论

    题目描述 题解 之前做过一次 假设图建好了,设g[i]表示i->j(i<j)的个数 那么ans=∏(n-g[i]),因为连出去的必定会构成一个完全图,颜色互不相同 从n~1染色,点i的方案 ...

  5. 6380. 【NOIP2019模拟2019.10.06】小w与最长路(path)

    题目 题目大意 给你一棵树,对于每一条边,求删去这条边之后,再用一条边(自己定)连接两个连通块,形成的树的直径最小是多少. 正解 首先,将这棵树的直径给找出来.显然,如果删去的边不在直径上,那么答案就 ...

  6. 6374. 【NOIP2019模拟2019.10.04】结界[生与死的境界]

    题目 题目大意 给你一个数列,每次可以选择任意两个相邻的数\(x\)和\(y\),将其删去,并在原来位置插入\(x+2y\). 每次询问一个区间,对这个区间进行上述操作.求最后剩下的数最大是多少. 答 ...

  7. 6424. 【NOIP2019模拟2019.11.13】我的订书机之恋

    题目描述 Description Input Output Sample Input 见下载 Sample Output 见下载 Data Constraint 题解 lj题卡线段树 求出每个右端点往 ...

  8. 【NOIP2019模拟2019.9.4】B(期望的线性性)

    题目描述: \(1<=n,ai<=5*10^5\) 题解: 我是弱智我不会期望线性. 设\(E(a[i])\)表示第i个期望被减的个数. \(E(a[1])=a[1]\) 不难发现\(E( ...

  9. 6368. 【NOIP2019模拟2019.9.25】质树

    题目 题目大意 有个二叉树,满足每个点跟它的所有祖先互质. 给出二叉树的中序遍历的点权,还原一种可能的方案. 思考历程 首先想到的当然是找到一个跟全部互质的点作为根,然后左右两边递归下去处理-- 然而 ...

随机推荐

  1. 静态部署TOMCAT

    常见部署方式:静态部署和容器化部署 一.下载tomcat安装包 下载地址:https://tomcat.apache.org/download-90.cgi 图上是显示最新版本,而我下载的是9.0.8 ...

  2. UVA1411 Ants

    想出的一道题竟然是原题QAQ 非常有趣的一个题 根据三角形两边之和大于第三边 所以相交的线段一定是比不相交的线段要长的 所以直接二分图构图 最小费用最大流即可 (我不管我不管我要把这个出到NOIP膜你 ...

  3. PyTorch 计算机视觉的迁移学习教程代码详解 (TRANSFER LEARNING FOR COMPUTER VISION TUTORIAL )

    PyTorch 原文: https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html 参考文章: https://www ...

  4. boost pointer container

    1. boost::ptr_vector #include <boost/ptr_container/ptr_vector.hpp> #include <iostream> i ...

  5. CDN(Content Delivery Network)内容分发网络

    CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各处放置节 ...

  6. PHP基础知识总结(五) php面试题

    1.Ajax跨域 json:数据交换格式,{"name":"wangtianle"} jsonp:非官方跨域数据交换协议,可以通过动态添加<script/ ...

  7. 三.通过jenkins对系统的监控(2)

    在这记录下,通过HTTP Request Plugin监控系统的异常.和上一篇原理差不多. 1.首先需要安装HTTP Request Plugin.插件安装好后,在系统设置下面会新增如下配置: 具体有 ...

  8. 【计算机网络mooc】二、物理层

    1.物理层基本概念 物理层只考虑传输bit流,不包括网线等传输媒体(可认为是第0层),屏蔽传输媒体的差异,不同的传输媒体定义不同标准. 主要任务:确定与传输媒体的接口的特性. 机械特性:网线上面的水晶 ...

  9. 基于turtle库的七段数码管绘制

    ·文章结构 >样例及概览 >函数框架分析 >功能发展·样例及概览 七段数码管,是信号灯.电子表等很多设备的显示形式.而利用python的turtle库,我们也可以模拟着写出一个动态生 ...

  10. 11.Jmeter 快速入门教程 -- jmeter事务控制器

    你肯定知道, jmeter是一个跨系统平台的性能测试工具, 比如他可以在linux,freebsd,windows,solaris 等等各种系统上可以运行. 我可以说, 事务 transaction ...