• 迷宫


    有趣的题目。

    实际上题目就是让我们构造一个自动机让节点数最小。

    有一个简单的构造:构造k个点,点i表示现在%k=i,点i向im+j(0<=j<m)连边,意思是前面的部分*=m,后面的加上当前这一位。

    这个构造的点数不是最小的。有一个定理可以用来求出最简自动机:

    定义2个节点a,b等价为:这两个节点中不能一个包含终态,一个不包含。若转移函数是f,则对于所有c,f(a,c)=f(b,c)。用并查集可以求出答案获得30分。

    考虑每次合并的时候在干什么。实际上,im=jm(%k)的2个点可以被合并,因为他们的转移是相同的。

    设f(i)表示i接受的最短串为多少,g(i)表示i*m^f(i)%k,则两个节点i,j当f(i)=f(j)且g(i)=g(j)可以合并。

    如果i*m^k=j*m^k,则走长度为k的串后,i接受的串集=j接受的串集。

    但是如果一个点能够走<k到达终点,则走的前面的串可能有一个节点可以接受而另一个不行的,不符合要求。

    通过这个条件,我们可以得到一个算法:每次把所有节点*k(这下节点i的值就是i*m^k),合并权值相同的点(这些点符合上面的合并要求)。

    然后删除序列末尾>i-m^k+1的点,每个点累加答案。

    原因是因为这些点在经过k次以后,有一条路径会经过0点,不符合条件,要全部删除。

    可以获得50分。

    接下来的素数的点可以推一下拿到另外10分。

    貌似有类欧拿到80分的做法,以后再学。

    满分的测试点需要更快的模拟这个过程。

    设d=gcd(k,m)

    若d=1,则每个节点的出边集都是不同的,无法合并。

    把所有点*=m%=k后,所有点都是d的倍数。

    若t=k/d,由数论知识可得1~k-1 *m%k的结果的循环节为t,d的所有倍数都会出现。

    前面的过程要求把*m%k相同的数合并。实际上可以合并(k-1)-t次

    现在还有t个节点。设k'=k/d,m'=m/d。由于d的倍数在集合内都出现了,所以后面的m'个数都要被删除。剩下的数是1,2,....k'-m'

    如果输入的数是n,k,要对节点1,2,....v去重。

    初始,v=k-1,m=1,k=k

    设d=gcd(k,m),t=k/d

    如果d=1,根据之前的分析无法合并

    若v<=t,则循环节未完全出现,乘以m得到的结果互不相同,无法合并

    若v>t,则所有节点可以被合并,合并完后还有t个点,则m'=m/(n/d)

    后面的m个点都被删除,所以新v=t-m',k'=t

    把所有数都除以d,递归到下一个子问题。

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int t,n,k;
    int gcd(int x,int y){
        return y?gcd(y,x%y):x;
    }
    signed main(){
        scanf("%lld",&t);
        while(t--){
            scanf("%lld%lld",&n,&k);
            int v=k-1,r=k,m=1;
            while(v>0){
                int d=__gcd(k,n),t=k/d;
                if(d==1||v<=t)break;
                r-=v-t;
                if(!(t/m/(n/d)))break;
                m*=n/d;
                v=t-m;
                k/=d;
            }
            printf("%lld
    ",r);
        }
    }
    View Code
  • 相关阅读:
    【JS】事件传播
    【JS】鼠标跟随
    【JS】使用JS实现回到顶部按钮功能
    【JS】DOM获取元素方法
    【JS】DOM操作元素
    【JS】实现全选功能
    【JS】定时器的开启与关闭
    【JS】动态渲染页面
    【JS】标签页切换
    Elasticsearch(ES)简介
  • 原文地址:https://www.cnblogs.com/cszmc2004/p/12957426.html
Copyright © 2020-2023  润新知