zoukankan      html  css  js  c++  java
  • Codeforces Round #647 (Div. 2) (D.Johnny and Contribution E.Johnny and Grandmaster 题解)(训练)

    D - Johnny and Contribution 

    题目大意

           给你m个顶点,n条边的无向图,每个顶点都有自己的期望w[i],将图中所有点填入数字,规则是在填任意一点时,其填入的数字是从1开始且这个点的邻居没有的最小数字,输出填图的顺序。

    解题思路

           首先,将所有期望是1的点全部填入1,将与其有一条边连接的点都填入2,若其中有点的期望值不是2,则说明不存在这种图,即直接退出,输出-1。                                                                                                                                                                                    以此类推,每次都将上一个期望值的邻居填入此次的期望值,每次记录填入数字的点,并判断是否符合该点的期望即可。

    代码

    #include<bits/stdc++.h>
    #define ll long long
    #define MOD 1000000007  
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    vector<int>v[500005];
    vector<int>vv[500005];
    vector<int>ans;
    int ss[500005];
    int w[500005];
    int main()
    {
        ll n,m;
        cin>>n>>m;
        int x,y;
        for(int i=1;i<=m;i++){
            scanf("%d %d",&x,&y);
            v[x].push_back(y);
            v[y].push_back(x);
        }
        for(int i=1;i<=n;i++){
            int c;
            scanf("%d",&c);
            vv[c].push_back(i);
            w[i]=1;
        }
        for(int i=1;i<=n;i++){
           for(auto j:vv[i]){
              if(w[j]!=i){
                  cout<<"-1";
                  return 0;
              }
              for(auto u:v[j]){
                  if(w[u]==i)w[u]++;
              }
              ans.push_back(j);
           }
        }
        for(auto i:ans){
           cout<<i<<" ";
        }
        return 0;
    }

    E - Johnny and Grandmaster

    题目大意

           给你n个数字k[i],再给你一个p,问你将k这个数组分成两部分,使两个部分的p的k[i]次方的差最小,问该差值最小是几?最终结果需要mod1000000007

    解题思路

           该问题在可以转化为求把一串数字分成两串,是两者的差值最小,由于该数组有p的幂次方组成,因此其中大数的影响一定比小数的影响大,分两种情况,1、大数减去其后的所有小数的num值大于等于0,则最终答案就是该num值。2、大数减去其后的小数的num值小于0,则需要在相减的过程中,如果出现num=0并且后面还有数字时,把前面的全部抛弃,将大数改为后一个小数(即当在减k[i]的p次的过程中等于0,则将k[i+1]的p次设为大数)。以此类推,最后得到的num,就是最小值。

            注意点:1、数字范围较大,在求幂的时候需要用快速幂。                                                                                                                              2、在相减过程中,会出现差值num=1000000007的情况,此时会出现误判0,所以需要在引入一个余数,来保证该差值num真的为0.

    代码

    #include<bits/stdc++.h>
    #define ll long long
    #define MOD 1000000007  
    #define INF 0x3f3f3f3f
    #define mem(a,x) memset(a,x,sizeof(a))  
    #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    ll fastpow(ll a,ll n,ll o)
    {
         ll base=a;
         ll res=1;
         while(n){
            if(n&1)
                res=(res*base)%o;
            base=(base*base)%o;
            n>>=1;
         }
         return res%o;
    }
    ll k[1000006];
    bool cmp(ll a,ll b)
    {
       return a>b;
    }
    int main()
    {
        ll t,n,p;
        ll e=12345678;
        scanf("%lld",&t);
        while(t--){
          scanf("%lld %lld",&n,&p);
          for(int i=1;i<=n;i++){
             scanf("%lld",&k[i]);
          }
          sort(k+1,k+n+1,cmp);
          ll num=0,num2=0;
          for(int i=1;i<=n;i++){
             ll temp=(fastpow(p,k[i],MOD)+MOD)%MOD;
             ll temp2=(fastpow(p,k[i],e)+e)%e;      //防止误判
             if(num==0&&num2==0){
                num=temp;         
                num2=temp2;     
             }else{
                num=(num+MOD-temp)%MOD;
                num2=(num2+e-temp2)%e;
             }
          }
          printf("%lld
    ",num);
        }
        return 0;
    }
    越自律,越自由
  • 相关阅读:
    牛客练习赛19 D-托米去购物
    牛客练习赛19 托米的简单表示法
    Codeforces Round #492 (Div. 2) [Thanks, uDebug!]
    Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017
    Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017
    Codeforces Round #491 (Div. 2) E
    I00018 生成全1数
    I00017 生成9开头的按位递减数
    I00017 生成9开头的按位递减数
    HDU1042 n!
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13435580.html
Copyright © 2011-2022 走看看