• ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined)


    A:

    B:

    C:   Molly's Chemicals(前缀和+map)

    题意:在这个数组里面取连续的一段,问有多少种取法使得这段的和为k的自然数幂次;

    思路:不能直接暴力,连续的自然联想到前缀和,假设要求和为x的数目,k的不同的幂次就是多个不同的x的计数和了;sum[i]-sum[j]=x,sum[i]-x=sum[j],累计sum[j]的数目就好了;

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn=1e5+10;
    int n,k;
    LL a[maxn];
    vector<LL>ve;
    map<LL,int>mp;
    int main()
    {
        cin>>n>>k;
        for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
        LL tep=1;
        for(int i=1;i<=60;i++)
        {
            if(abs(tep)>1e14)break;
            ve.push_back(tep);
            tep=tep*k;
        }
        sort(ve.begin(),ve.end());
        int len=unique(ve.begin(),ve.end())-ve.begin();
       // for(int i=0;i<len;i++)cout<<ve[i]<<endl;
        LL ans=0,sum=0;
        mp[0]++;
        for(int i=1;i<=n;i++)
        {
            sum=sum+a[i];
            for(int j=0;j<len;j++)
            {
                LL temp=ve[j];
                ans=ans+mp[sum-temp];
            }
            mp[sum]++;
        }
        cout<<ans;
        return 0;
    }
    

      

    D:  The Door Problem(2-SAT)

    题意:有m个开关和n个门,每个门都是由两个开关控制,但每个开关控制可能不止一个门,现在给出初始的门的开闭状况,问是否有一种方法使所有的门都打开;

    思路:由于每个门都是由两个开关控制,所以对于门为1(开)应该只有一个开关变化,对于门为0(闭)两个开关要么都变要么都不变,这就是2-SAT的问题的模型了;

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+4;
    int n,m,r[maxn],s[2*maxn],c=0;
    vector<int>ve[maxn],G[maxn*2];
    bool mark[2*maxn];
    bool dfs(int x)
    {
        if(mark[x^1])return false;
        if(mark[x])return true;
        mark[x]=true;
        s[c++]=x;
        for(int i=0;i<G[x].size();i++)
        {
            if(!dfs(G[x][i]))return false;
        }
        return true;
    }
    inline void add(int x,int xval,int y,int yval)
    {
        x=x*2+xval;
        y=y*2+yval;
        G[x^1].push_back(y);
        G[y^1].push_back(x);
    }
    bool solve()
    {
        for(int i=0;i<m*2;i+=2)
        {
            if(!mark[i]&&!mark[i+1])
            {
                c=0;
                if(dfs(i))
                {
                    while(c>0)mark[s[--c]]=false;
                    if(!dfs(i+1))return false;
                }
                else return false;
            }
        }
        return true;
    }
    int main()
    {
        memset(mark,0,sizeof(mark));
         scanf("%d%d",&n,&m);
         for(int i=1;i<=n;i++)scanf("%d",&r[i]);
         for(int i=0;i<m;i++)
         {
             int x,y;
             scanf("%d",&x);
             for(int j=1;j<=x;j++)
             {
                 scanf("%d",&y);
                 ve[y].push_back(i);
             }
         }
         for(int i=1;i<=n;i++)
         {
             int u=ve[i][0],v=ve[i][1];
             if(r[i])add(u,0,v,1),add(u,1,v,0);
             else add(u,0,v,0),add(u,1,v,1);
         }
        if(solve())puts("YES");
        else puts("NO");
        return 0;
    }
    

      

    E: The Holmes Children(数论)

    题意:给出了这个公式,和f(n)和g(n)的公式,求给定的n和k下的函数值;

    思路:f(n)是满足x+y=n&&gcd(x,y)==1的(x,y)对数,即gcd(x,n-x)==1的对数,就是欧拉函数值phi(n),g(n)=∑f(n/d)(d|n)=n;Fk(n)等于(k+1)/2层欧拉函数,所以就变成了一道简单题啦;

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL n,k;
    const int maxn=1e6+10;
    const LL mod=1e9+7;
    int vis[maxn],cnt=0;
    LL prime[maxn];
    inline void init()
    {
        for(int i=2;i<maxn;i++)
        {
            if(!vis[i])
            {
                prime[cnt++]=i;
                for(int j=2*i;j<maxn;j+=i)vis[j]=1;
            }
        }
    }
    LL phi(LL x)
    {
        LL tep=x;
        for(int i=0;i<cnt;i++)
        {
            if(x<prime[i])break;
            if(x%prime[i]==0)
            {
                tep=tep/prime[i]*(prime[i]-1);
                while(x%prime[i]==0)x/=prime[i];
            }
        }
        if(x>1)tep=tep/x*(x-1);
        return tep;
    }
    LL solve(LL cur,LL num)
    {
        if(cur==1)return 1;
        if(num==0)return cur;
        return solve(phi(cur),num-1);
    }
    int main()
    {
        init();
        cin>>n>>k;
        k=(k+1)/2;
        cout<<solve(n,k)%mod;
        return 0;
    }
    

      

  • 相关阅读:
    spring学习(十七)--annotion注解
    spring学习(十六)--spring方式实现工程初始化配置
    spring学习(十五)--自己实现BeanFactory
    JDBC使用SPI机制解析
    SPI机制
    spring学习(十三)--自己实现SpringServletContainerInitializer
    cetnos基本操作
    CentOS基本命令
    面向对象的双下方法
    Flask数据连接池 DBUtils
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/6442929.html
Copyright © 2020-2023  润新知