• 2020牛客多校第7场训练赛H Dividing


    题意: 对于Legend Tuple(下文称为LT)有以下3种规则:

        1、(1,k)必然符合要求;

        2、如果(n,k)符合要求,则(n+k,k)也符合要求;

        3、如果(n,k)符合要求,则(n*k,k)也符合要求。

      给出N、K,分别为n、k的范围,问有多少符合要求的LT。

    思路:我们可以先看一下N==3,K==3时。

               k=1:(1,1),(2,1),(3,1);

          k=2: (1,2),(3,2),(2,2);

       k=3:   (1,   3),(3, 3)  共8种。

            我们一开始都是把n固定为1,而k取[1,K]中的一个值,然后用第2、3规则取“扩散”出去找到别的。

      这里我们就很明显是个bfs的思想了,但这题必不可能是bfs,不过不妨碍我们先打个表来看看。

      //此处果断喊来队伍的工具人

     

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long

    int n,k,ans=0;
    bool vis[10005];

    void bfs(int x)
    {
      memset(vis,false,sizeof(vis));
      queue<int>q;
      q.push(1);
      vis[1]=true;
      ans++;
      while(!q.empty()){
      int now=q.front();
      int x1=now+x,x2=now*x;
      if(x1<=n&&!vis[x1]){
          q.push(x1);
          vis[x1]=true;
          ans++;
      }
      if(x2<=n&&!vis[x2]){
        q.push(x2);
        vis[x2]=true;
        ans++;
       }
      q.pop();
      }
    }

    int main()
    {
      int t;
      cin>>t;
      while(t--){
        cin>>n>>k;
        ans=0;
        for(int i=1;i<=k;i++){
          bfs(i);
        }
      cout<<ans<<endl;}
      return 0;
    }

      得表:

          第21行是用第20行做的差。

      当K>N时,对于任意的(1,i)/*i>N*/对于答案的贡献只有1。

      当K<=N时,(1,i)/*i==N*/对于答案的贡献为2.

      当K<N时,考虑i取不同值时对于答案的贡献。

          i<=2,ans+=N;

          2<i<=N,ans+=(n/i)*2+(i*i==N?0:1)/*原谅我不会打向上取整,嘤嘤嘤。。。*/

          这里有个重点,也是这题为什么循环能AC的原因。我们不难看出在[3,N]这个区间上,有很多连续的区间,在这些区间上N/i是相同的。那么我们就可以跳着去累加,而不需要一个一个去看。

      代码如下:

      

    #include<bits/stdc++.h>
    using namespace std;
      
    #define ll long long
      
    ll mod=1e9+7;
    int main()
    {
        ll N,K;
        while(cin>>N>>K)
        {
            if(N==1){cout<<K%mod<<endl;continue;}
            ll ans=0;
            if(K>=N)
            {
                ans=(K-N)%mod;
                K=N-1;
                ans=(ans+2)%mod;
            }
            bool f=true;
            for(ll i=1; i<=K&&f; i++)
            {
                if(i<=2)ans=(ans+N)%mod;
                else
                {
                    ll x=N/i;//x 6  i 3
                    if(x*i==N)ans=(ans+2*x)%mod;
                    else
                    {
                        ll y=N/x;//3
                        if(y>K)
                        {
                            f=false;
                            y=K;
      
                        }
                        if(y*x==N)y--;
                        ans=(ans+  ((y-i+1)*x*2)%mod   +(y-i+1)%mod  )%mod;
                    
                            i=y;
                    }
      
                }
            }
            cout<<ans<<endl;
        }
      
        return 0;
    }

      

  • 相关阅读:
    怎样删除数据库中的反复记录?
    GitHub上最受欢迎的Android开源项目TOP20
    hdu2066一个人的旅行
    《Head First 设计模式》学习笔记——模板方法模式
    C语言盲点笔记1
    北大光华管理学院院长蔡洪滨:商学院需要有灵魂_网易财经
    戴修宪_百度百科
    [对话CTO]当当网熊长青:兴趣是成为优秀工程师的第一因素-CSDN.NET
    【网络金融部团队及负责人,太平洋证券股份有限公司】前程无忧官方招聘网站
    辞职穷半年,转行穷三年!!
  • 原文地址:https://www.cnblogs.com/yzxqq/p/13415384.html
Copyright © 2020-2023  润新知