【NOIP2019模拟2019.10.07】果实摘取 (约瑟夫环、Mobius反演、类欧、Stern-Brocot Tree)
Description:
小 D 的家门口有一片果树林,果树上果实成熟了,小 D 想要摘下它们。
为了便于描述问题,我们假设小 D 的家在二维平面上的 (0, 0) 点,所有坐标范围的绝对值不超过 N 的整点坐标上都种着一棵果树。((0, 0) 这个点没有果树)
小 D 先站在 (0, 0) 处,正对着 (1, 0) 的方向。
每次摘果实时,小 D 会逆时针选择他能看到的第 K 棵还未摘取果实的果树,然后向着这个方向走去,在行走的过程中摘下沿路的所有的果树上的果树果实,直到走到果树林的边缘。
接下来,小 D 回到 (0, 0) 处,正对着上一次摘果实的果树的方向。
小 D 会重复这个过程,直到所有的果实都被摘取,小 D 感兴趣的是,最后一棵被摘下果实的果树是哪一棵?
注意小 D 不能看到被任何其他果树遮挡着的果树。
1 ≤ N, K ≤ 10^5
题解:
考虑总共的直线个数是\(8\sum_{i=1}^n\phi(i)\)。
第一个问题是\(n=8\sum_{i=1}^n\phi(i)\)的环,每次取当前数的第k个,最后剩哪个的约瑟夫问题。
约瑟夫递推式(编号0-n-1):
\(f[1]=0,f[n]=(f[n-1]+k)~mod~n\)
推导显然很简单:
假设从0开始,第一次取了k-1,剩下\(k,k+1,…,n-1,0,1,…k-2\),以这个做一个\(n-1\)的子问题,得到的答案加k模n就是了。
由于\(n很大\),这个递推式显然会超时。
当n远大于k时,很久才会模一次,不妨一次跳多步,假设要x步,相当于下面的不等式:
\(f[n]+k*x>=n+x\)
\(x=\lceil{n-f[n] \over k - 1}\rceil\)
估计复杂度,当\(n<=k\)时,\(x=1\)
当\(n>k\)时,每次要加上\(n/k\)左右,也就是乘上\({k+1\over k}\)。
所以大概是\(O(k+log_{k+1\over k}~n)≈O(k ~ln ~n)\)。
第2个问题是求第x条直线,先全部转成第一象限。
这个比较套路,在Stern-Brocot Tree上二分,然后变成数数问题,
\(cnt=\sum_{i=1}^n\sum_{j=1}^n[(i,j)=1]*[{j\over i}<{b \over a}]\)
\(=\sum_{d=1}^n\mu(d)\sum_{i=1}^{\lfloor n/d \rfloor}min({\lfloor(b*i)/a\rfloor},\lfloor n/d \rfloor)\)
预处理\(\mu\)的前缀和,每次查询分块+类欧即可。
总复杂度:
\(O(k~ln~n+n(n^{2/3})+\sqrt n *log^3n)\)
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int N = 1e5 + 5;
int n, k;
int bz[N], p[N], p0, mu[N], phi[N], smu[N];
void sieve(int n) {
phi[1] = mu[1] = 1;
fo(i, 2, n) {
if(!bz[i]) p[++ p0] = i, phi[i] = i - 1, mu[i] = -1;
for(int j = 1; i * p[j] <= n; j ++) {
int k = i * p[j]; bz[k] = 1;
if(i % p[j] == 0) {
phi[k] = phi[i] * p[j];
mu[k] = 0;
break;
}
phi[k] = phi[i] * phi[p[j]];
mu[k] = -mu[i];
}
}
fo(i, 1, n) smu[i] = smu[i - 1] + mu[i];
}
ll divs(ll x, ll y) {
return x / y + (x % y != 0);
}
ll calc(ll n, ll m) {
if(m == 1) return n;
ll x = 1, s = 0;
while(x < n) {
ll k = divs(x - s, m - 1);
if(x + k > n) return s + (n - x) * m + 1;
x += k; s = (s + m * k) % x;
}
return s + 1;
}
ll calc(ll n, ll a, ll b, ll c) {
if(n < 0) return 0;
if(a >= c || b >= c) return calc(n, a % c, b % c, c) + n * (n + 1) / 2 * (a / c) + (n + 1) * (b / c);
ll m = (a * n + b) / c;
return n * m - calc(m - 1, c, c - b - 1, a);
}
ll ca(int n, int a, int b) {
ll m = (ll) b * n / a;
if(n <= m) { return calc(n, a, 0, b);}
return calc(m, a, 0, b) + (ll) (n - m) * n;
}
ll count(int b, int a) {
ll ans = 0;
for(int i = 1, j; i <= n; i = j + 1) {
j = n / (n / i);
ans += ca(n / i, b, a) * (smu[j] - smu[i - 1]);
}
return ans;
}
ll sp;
int ax, ay;
void work(ll t) {
int x1 = 0, y1 = 1, x2 = 1, y2 = 0;
while(1) {
int x3 = x1 + x2, y3 = y1 + y2;
if(max(x3, y3) > n) break;
if(count(x3, y3) <= t) {
int c = 1;
while(1) {
int x4 = x3 + c * x2, y4 = y3 + c * y2;
if(x4 > n || y4 > n || count(x4, y4) > t) break;
c *= 2;
}
for(; c; c /= 2) {
int x4 = x3 + c * x2, y4 = y3 + c * y2;
if(x4 <= n && y4 <= n && count(x4, y4) <= t) x3 = x4, y3 = y4;
}
x1 = x3, y1 = y3;
ax = x3, ay = y3;
} else {
int c = 1;
while(1) {
int x4 = x3 + c * x1, y4 = y3 + c * y1;
if(x4 > n || y4 > n || count(x4, y4) <= t) break;
c *= 2;
}
for(; c; c /= 2) {
int x4 = x3 + c * x1, y4 = y3 + c * y1;
if(x4 <= n && y4 <= n && count(x4, y4) > t) x3 = x4, y3 = y4;
}
x2 = x3, y2 = y3;
}
}
int c = min(n / ax, n / ay);
ax *= c, ay *= c;
swap(ax, ay);
}
int main() {
freopen("garden.in", "r", stdin);
freopen("garden.out", "w", stdout);
sieve(1e5);
scanf("%d %d", &n, &k);
fo(i, 1, n) sp += 2 * phi[i];
ll t = calc(sp * 4, k);
if(t <= sp) {
if(t == 1) ax = n, ay = 0; else
work(t - 1);
} else
if(t <= 2 * sp) {
if(t == sp + 1) ax = 0, ay = n; else
work(2 * sp - t + 1), ax = -ax;
} else
if(t <= 3 * sp) {
if(t == 2 * sp + 1) ax = -n, ay = 0; else
work(t - 2 * sp - 1), ax = -ax, ay = -ay;
} else {
if(t == 3 * sp + 1) ax = 0, ay = -n; else
work(4 * sp - t + 1), ay = -ay;
}
pp("%d %d\n", ax, ay);
}
【NOIP2019模拟2019.10.07】果实摘取 (约瑟夫环、Mobius反演、类欧、Stern-Brocot Tree)的更多相关文章
- 6383. 【NOIP2019模拟2019.10.07】果实摘取
题目 题目大意 给你一个由整点组成的矩形,坐标绝对值范围小于等于\(n\),你在\((0,0)\),一开始面向\((1,0)\),每次转到后面第\(k\)个你能看到的点,然后将这条线上的点全部标记删除 ...
- 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]
题目描述 题解 随便bb 详细题解见 https://www.cnblogs.com/coldchair/p/11624979.html https://blog.csdn.net/alan_cty/ ...
- 6392. 【NOIP2019模拟2019.10.26】僵尸
题目描述 题解 吼题但题解怎么这么迷 考虑一种和题解不同的做法(理解) 先把僵尸离散化,h相同的钦(ying)点一个大小 (可以发现这样每种情况只会被算正好一次) 计算完全被占领的方案,然后1-方案/ ...
- 6389. 【NOIP2019模拟2019.10.26】小w学图论
题目描述 题解 之前做过一次 假设图建好了,设g[i]表示i->j(i<j)的个数 那么ans=∏(n-g[i]),因为连出去的必定会构成一个完全图,颜色互不相同 从n~1染色,点i的方案 ...
- 6380. 【NOIP2019模拟2019.10.06】小w与最长路(path)
题目 题目大意 给你一棵树,对于每一条边,求删去这条边之后,再用一条边(自己定)连接两个连通块,形成的树的直径最小是多少. 正解 首先,将这棵树的直径给找出来.显然,如果删去的边不在直径上,那么答案就 ...
- 6374. 【NOIP2019模拟2019.10.04】结界[生与死的境界]
题目 题目大意 给你一个数列,每次可以选择任意两个相邻的数\(x\)和\(y\),将其删去,并在原来位置插入\(x+2y\). 每次询问一个区间,对这个区间进行上述操作.求最后剩下的数最大是多少. 答 ...
- php解决约瑟夫环
今天偶遇一道算法题 "约瑟夫环"是一个数学的应用问题:一群猴子排成一圈,按1,2,-,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数, 再数到第m只,在把 ...
- 51nod 1073 约瑟夫环
题目链接 先说一下什么是约瑟夫环,转自:传送门 关于约瑟夫环问题,无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),当n,m非常大( ...
- Java实现约瑟夫环
什么是约瑟夫环呢? 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个 ...
随机推荐
- php max()函数 语法
php max()函数 语法 作用:从所有参数中找到最大数 语法:max(X,Y,Z) 或者max(array(X,Y,Z)) 参数:max函数中参数至少一个,可以多个参数,也可以是数组. 说明:如果 ...
- tracert命令 -网络管理命令
Tracert是路由跟踪程序,用于确定 IP 数据报访问目标所经过的路径.Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其他主机的路由. 在工作 ...
- Maven之搭建本地私服(nexus)仓库
摘要:现在越来越多的项目都在使用Maven管理项目,尤其是在大型的项目团队中使用Maven能带来更加多的好处,私服的好处我相信大家都明白,在这里我就不多说了,它最重要的作用就是可以让项目团队成员更加方 ...
- Apache + Tomcat 集群的配置
公司最近新接了一个项目,客户要求WEB SERVER 必须是APACHE,,由于之前的项目一直都是NGINX,,无奈啊,,由于对方的IT又是在三哥的过度,经过一番的争执只能顺应三哥三姐的要求..
- mysql隔离级别相关
1.原子性.隔离性.一致性.持久性 2.mysql并发控制可能出现的问题: 脏读(A事务读取到B事务未commit的数据后,B事务回滚) 不可重复读(A事务第一次读到的数据,被B事务更新数据后,第二次 ...
- mysql 查询结果增加自动递增的一列,排名,排序
mysql中有时候需要对查询的结果排序,比如根据成绩获取排名信息等,需要增加一个自增的列,也就是排名信息 ; as sortid FROM a; 如果不支持写两条sql,可以用以下写法合成一条sq ...
- MySQL-初始化和自动更新TIMESTAMP和DATETIME
https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html 例,添加自动更新的保存最后一次修改该条记录的时间戳的字段: ...
- python分类预测模型的特点
python分类预测模型的特点 模型 模型特点 位于 SVM 强大的模型,可以用来回归,预测,分类等,而根据选取不同的和函数,模型可以是线性的/非线性的 sklearn.svm 决策树 基于" ...
- Hive SQL语法总结
Hive是一个数据仓库基础的应用工具,在Hadoop中用来处理结构化数据,它架构在Hadoop之上,通过SQL来对数据进行操作. Hive 查询操作过程严格遵守Hadoop MapReduce 的作业 ...
- BootStrap的一些基本语法
一, 1.@using :引入命名空间 2.@model:声明强类型的数据 Model 类型 3.@section:定义要实现母版页的节信息 4.@RenderBody():当创建基于此布局页面的视图 ...