原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ375.html

题解

首先,我们可以建出一个 k 个点的自动机,第 i 个点表示当前数对 k 取模为 i-1。显然每一个点有 m-1 条出边。

然后,稍加观察,我们就可以发现,如果一些节点的出边集合是相同的,我们就可以将他们合并。

具体是怎样的节点呢?

对于每一个 $t$ ,满足

$$im \equiv t\pmod k $$

的所有 $i$ 都可以合并(节点 0 除外)。

然后你就发现你几乎过了大样例的前 100 个数据。

只有很少是错的。

所以大概会得到0分的好成绩。

那么错在了哪儿?

并不是这样合并完了就没有节点可以合并了。

我们再想想哪些节点可以合并。

注意到如果 $im^2\equiv jm^2\pmod k $ 的话,只要在后面接上两个字母,$i$ 和 $j$ 就没区别了。

但是如果其中一个走一步就可以到 0 了,另一个不行,那么他们就是不等价的。

除此之外的情况都可以合并。

类似地,对于 $m^3,m^4,m^5,\cdots$ 也差不多。

于是我们就可以得到一个 $O(k\log ^2 k)$ 的模拟。

可以获得 50 分的好成绩。

再看看质数的情况,由于当 $\gcd(k,m)=1$ 时,答案等于 $k$ ,所以 $k$ 一定是 $m$ 的倍数。稍微模拟一下可以发现,一次合并之后相当于缩小了问题规模,而去求 $k'=k/m,m'=m$ 的子问题。简单推导一下就可以得到质数的10分。

现在已经得到了 60 分的好成绩。

现在我们来看看 60 分的做法给了我们什么启发:缩小问题规模。

设 $d = \gcd(k,m)>1$ ,则一开始给 $1\cdots k-1$ (0是特殊点被ban掉了)乘了 m 模了 k 之后,所有数都是 d 的倍数。

设 $t=\frac kd$ ,则 $1\cdots k-1$ 乘m模k 后的结果是 $t$ 个一循环的,所以 d 的每一个倍数都会出现。我们把每一种乘m模k相同的缩起来显然是最优的,那么,我们可以合并 $(k-1) - t$ 次。

现在还剩下 $t$ 个节点,注意到现在加上 $0\cdots m-1$ 之后与 k 同余的节点显然不能参与下一次合并,所以我们要把他们扔掉。

扔掉的是那些呢?

好像有点棘手。我们先绕个弯。之前说道这里的所有数都是 d 的倍数。所以我们把所有值都除以 d,k' = k/d, m'=m/d 。由于之前提到 " d 的每一个倍数都会出现",所以所有值除以 d 之后,得到的就是 $1,2,\cdots , k'-1$ 。我们扔掉后 $m'$ 个数,所以剩下的就是 $1,2,\cdots ,k'-m$ 。

我们发现我们得到了一个原问题的子问题。

于是我们可以考虑把这种问题一般化:

假设读入的两个数第一个是 n ,第二个是 k 。

假设当前剩余节点 $1,2,\cdots ub$ ,$m$ 为 $n$ 的若干次幂除以一些 gcd ,$k$ 表示除过一些 gcd 的 k ,在这种状态下,我们来计算最多可以合并多少节点。初始情况下, ub = k - 1, m = 1, k = k 。

令 $d = \gcd(k,n),t=k/d$ ,

考虑分几种情况讨论:

1.  d = 1: 显然不能合并。

2.  $ub\leq t$: 乘以 m 之后的得到的结果互不相同,所以也不能合并。

3.  这种情况下可以合并 $ub - t$ 次。合并完之后,显然还剩 $t$ 个点。这时候 $m' = m\cdot (n/d)$,扔掉 $m'$ 个点之后还剩 $t-m'$ 个,所以 $ub' = t - m'$ ,剩下就是 $k' = t$ 。

注意一下运算的时候不要爆 long long 。

于是你就可以得到 100 分的好成绩。

代码1 - 60分

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
LL T,n,k;
LL gcd(LL a,LL b){
return b?gcd(b,a%b):a;
}
vector <int> v;
int tn(int x){
return x?x:k;
}
int main(){
T=read();
while (T--){
n=read(),k=read();
if (gcd(n,k)==1){
printf("%lld\n",k);
continue;
}
if (n>1e5||k>1e5){
LL ans=k,c=0;
while (ans%n==0)
ans/=n,c++;
printf("%lld\n",ans+c);
continue;
}
LL m=1,ans=k;
v.clear();
For(i,0,k-1)
v.pb(tn(i));
while (1){
sort(v.begin(),v.end());
// outvec(v);
if (v.empty())
break;
int cnt=unique(v.begin(),v.end())-v.begin();
while (v.size()>cnt)
v.pop_back(),ans--;
// outvec(v);
while (!v.empty()&&v.back()>k-m)
v.pop_back();
// outvec(v);
for (auto &i : v)
i=tn(i*n%k);
if (k/m==0)
break;
m*=n;
}
cout<<ans<<endl;
}
return 0;
}

  

代码2 - 100分

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
using namespace std;
typedef long long LL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
LL T,n,k;
LL gcd(LL a,LL b){
return b?gcd(b,a%b):a;
}
int main(){
T=read();
while (T--){
n=read(),k=read();
LL ans=k,ub=k-1,m=1;
while (ub>0){
LL d=gcd(k,n),t=k/d;
if (d==1||ub<=t)
break;
ans-=ub-t;
if (t/m/(n/d)==0)
break;
m*=n/d;
ub=t-m;
k/=d;
}
printf("%lld\n",ans);
}
return 0;
}

  

UOJ#375. 【ZJOI2018】迷宫的更多相关文章

  1. 【BZOJ5213】[ZJOI2018]迷宫(神仙题)

    [BZOJ5213][ZJOI2018]迷宫(神仙题) 题面 BZOJ 洛谷 题解 首先可以很容易的得到一个\(K\)个点的答案. 构建\(K\)个点分别表示\(mod\ K\)的余数.那么点\(i\ ...

  2. bzoj5213: [Zjoi2018]迷宫

    好题!话说省选的都开始构造了吗 由于有K的倍数的限制所以不妨取模,先建K个点表示0~K-1这些数,第i个点向[i*m,i*m+m]建边.不难发现这是合法的但不一定是最优的 考虑合并等价的点,首先从直观 ...

  3. yyb省选前的一些计划

    突然意识到有一些题目的计划,才可以减少大量查水表或者找题目的时间. 所以我决定这样子处理. 按照这个链接慢慢做. 当然不可能只做省选题了. 需要适时候夹杂一些其他的题目. 比如\(agc/arc/cf ...

  4. yyb博客的几道神仙题

    该比赛链接 T5 题意: 给你一个\(n\times n\)的网格,开始有\(m\)个被涂成黑色的格子,如果存在三个格子\((x,y)\),\((y,z)\),\((z,x)\)满足\((x,y)\) ...

  5. UOJ#373. 【ZJOI2018】线图 搜索,树哈希,动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ373.html 前言 真是一道毒瘤题.UOJ卡常毒瘤++.我卡了1.5h的常数才过QAQ Orzjry 标算居然是指数做法 ...

  6. UOJ#374. 【ZJOI2018】历史 贪心,LCT

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ374.html 题解 想出正解有点小激动. 不过因为傻逼错误调到自闭.不如贺题 首先我们考虑如何 $O(n ...

  7. 【刷题】UOJ #374 【ZJOI2018】历史

    九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的小说,这本小说的架空世界引起了她的兴趣. 这个世界有 \(n\) 个城市,这 \(n\) 个城市被恰好 \(n-1\) 条双向道路联通, ...

  8. 【BZOJ5211】[ZJOI2018]线图(树哈希,动态规划)

    [BZOJ5211][ZJOI2018]线图(树哈希,动态规划) 题面 BZOJ 洛谷 题解 吉老师的题目是真的神仙啊. 去年去现场这题似乎骗了\(20\)分就滚粗了? 首先\(k=2\)直接算\(k ...

  9. 【转载】C/走迷宫代码

    1 #include<iostream> 2 #include<windows.h> 3 #include"GotoXY.h" 4 #include < ...

随机推荐

  1. Codeforces Round #551 (Div. 2)

    传送门 B. Serval and Toy Bricks 题意: 有一些规格相同的方块摆放在 n×m 的矩阵 h 中,h[i][j]代表第 (i,j) 个矩阵摆放的方块的高度: 现给你三个视图: 正视 ...

  2. zabbix模板化监控

    zabbix模板化监控 1. 实验简述 在zabbix监控中,有很多组的概念,具体有以下几种: 1. 主机和主机组,相同类型/应用的主机,可以归属于同一个主机组 2. item和application ...

  3. I/O模型系列之三:IO通信模型BIO NIO AIO

    一.传统的BIO 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请 ...

  4. Jupyter Notebook 的安装使用以及 tree 路径变更

    由于最近开始学习 Python,进而接触到一个十分强大的交互式编辑器 — Jupyter Notebook,用起来也非常顺手,于是记录一下相关的使用过程. 一.安装 Python: ①首先前往 pyt ...

  5. NCE损失(Noise-Constrastive Estimation Loss)

    1.算法概述 假设X是从真实的数据(或语料库)中抽取的样本,其服从一个相对可参考的概率密度函数P(d),噪音样本Y服从概率密度函数为P(n),噪音对比估计(NCE)就是通过学习一个分类器把这两类样本区 ...

  6. H5_0005:JS判断域名和时间有效期的方法

    (function () { var n = { c: function (t, e) { //console.log("c"); //把i(15)的d数组转换成字串 for (v ...

  7. PMP知识点(六)——项目经理权利类型

    社会心理学家约翰.弗伦奇(John.French)和伯特伦.雷文(Bertram.Raven)在他们1959年发表的一篇迄今不朽的论文中,提出了五种权力类别的模型,这个模型折射出权力拥有者依赖的不同基 ...

  8. 使用onblur+alert+focus导致的死循环解决

    <input type="text" id="loginName" onblur="checkLoginName()"/> fu ...

  9. python中opencv的安装

    1.得到opencv的安装包: 2.把安装包中的cv.py, cv2.pd放到一个文件夹中,并把这个文件夹放到D:\Anaconda2\Lib\site-packages中: 3.添加新的变量,变量名 ...

  10. 2.安装以太坊客户端(mac os)

    今天讲解在 mac系统下如何安装以太坊平台( Ethereum client) 1.以太坊客户端的介绍 从项目早期,为了适应不同系列的开发语言和操作系统,以太坊的团队就实现过很多客户端.如下面我们看到 ...