ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[Luogu5181][COCI2009]GENIJALAC

2019-02-13 15:44:06  阅读:206  来源: 互联网

标签:Luogu5181 const COCI2009 int ll GENIJALAC St 循环 Lcm


题目链接:

Luogu5181

一个简单题?

首先对\([C+1,n-D]\)中的每个数字求出循环节,求\(Lcm\)即是整段的循环节。

然后判断\([A,B]\)中有几个数满足\(x-1\equiv 0(mod\ Lcm)\)。

求循环节暴力可过。。

其实求循环节是可以\(O(n)\)的。

每一次求循环节得到一个环,那么环上所有点的循环节都是此次求出的循环节。

那么就可以\(O(n)\)得到所有循环节。

代码:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
typedef long long ll;

const ll llMax=1e13;
ll Gcd(const ll a,const ll b){return b?Gcd(b,a%b):a;}
ll Lcm(const ll a,const ll b){return a/Gcd(a,b)*b;}
int n,s[500005];
bool v[500005];
ll a,b,c,d,Mfo=1;

void DFS(const int x,const int St,const int Nt)//x 现在的位置 St 此次起点 Nt 已经经过节点数
{
    if(v[x])
    {
        if(x!=St)puts("0"),exit(0);//形成环,但是St不在环上,即St没有循环节
        Mfo=Lcm(Mfo,Nt);//求Lcm
        if(Mfo>=llMax)puts("0"),exit(0);//循环节过大,那么[A,B]中没有满足要求的数
        return;
    }
    v[x]=true,DFS(s[x],St,Nt+1);
}

int main()
{
    std::cin>>n>>a>>b>>c>>d;
    for(int i=1;i<=n;++i)scanf("%d",&s[i]);
    for(int i=c+1;i<=n-d;++i)
        if(!v[i])DFS(i,i,0);//不求减去的
    ll l=std::max(a-1,(ll)1),r=std::max(b-1,(ll)1);//把[A,B]中所有数-1,求有多少数是Lcm的倍数
    if(l%Mfo)l=(l/Mfo+1)*Mfo;
    if(r%Mfo)r=r/Mfo*Mfo;
    std::cout<<(r-l)/Mfo+1+(a==1)<<std::endl;//特判第1个
    return 0;
}

标签:Luogu5181,const,COCI2009,int,ll,GENIJALAC,St,循环,Lcm
来源: https://www.cnblogs.com/LanrTabe/p/10370039.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有