zoukankan      html  css  js  c++  java
  • E:Johnny and Grandmaster

    Johnny and Grandmaster

    思路

    这道题就是把一组数分成两个集合,使这两个集合的对p的次方的和的差的最小值,也就是求(sum1 - sum2)得最小值, 由于结果过大我们可能需要对结果取模。那么这题得关键在于我们应该如何分配这两个集合,也就是如何得到最优的(sum1 - sum2)的值。

    我们先把给定的数组从大到小排序,我们一定可以得到(p ^ {a[1]} = p ^ {a[2]} + p ^ {a[3]} + p ^ {a[4]} …… + p ^ {a[x]}),这一点是显然成立的。

    我们先分配最大的数到集合(1)中,接下来我们再分配其他的数到集合(2),中,直到(sum1 == sum2),我们再重新分配一个数到集合(1)中,重复如此操作我们就可以的到最小值。

    这题的关键就在于我们如何判断这两个集合中的数和是相等的,容易想到(sum1 == sum2 -> sum1 - sum2 == 0),于是我们好像可以利用这个点来完美的实现这个算法,但是很遗憾,wa在了test7,这里可能存在一个极大的误差,当我们的刚好是模数的时候,显然这里就错了,所以我们必须选定一个方法来避免这个错误,于是就有了,双模数判定差值是否为0。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    inline ll read() {
        ll f = 1, x = 0;
        char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-')    f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            x = (x << 3) + (x << 1) + (c ^ 48);
            c = getchar();
        }
        return f * x;
    }
    
    const int mod = 1e9 + 7,  MOD = 1e9 + 3;//用两个模数来判断是否为零,
    const int N = 1e6 + 10;
    
    ll a[N];
    
    ll qpow(ll a, ll n, ll mod) {
        ll ans = 1;
        while(n) {
            if(n & 1)   ans = (ans * a) % mod;
            a = (a * a) % mod;
            n >>= 1;
        }
        return ans;
    }
    
    int main() {
        // freopen("in.txt", "r", stdin);
        int t = read();
        while(t--) {
            int n = read(); ll p = read();
            for(int i = 1; i <= n; i++)
                a[i] = read();
            sort(a + 1, a + 1 + n, greater<ll> ());
            char *str = "okkkk";
            ll ans1 = 0, ans2 = 0;
            for(int i = 1; i <= n; i++) {
                if(!ans1 && !ans2) {//当这两个数同时为零的时候代表两个集合的差值为零。
                    ans1 = (ans1 + qpow(p, a[i], mod)) % mod;
                    ans2 = (ans2 + qpow(p, a[i], MOD)) % MOD;
                }
                else {
                    ans1 = (ans1 + mod - qpow(p, a[i], mod)) % mod;
                    ans2 = (ans2 + MOD - qpow(p, a[i], MOD)) % MOD;
                }
            }
            printf("%lld
    ", ans1);
        }
        return 0;
    }
    
  • 相关阅读:
    oracle的分析函数over 及开窗函数
    ASP.NET中分布式事务的使用
    后台实现显示欢迎用户登陆的方法
    AjaxHelper的get和post请求的封装类
    登陆权限验证Session和Cookie用法及BasePage类使用
    四个常用.NET的SqlHelper的方法
    ASP.NET在实际开发中验证码的用法
    SQL Server事务的存储过程
    利用JQuery实现全选和反选的几种方法
    JS中表格的全选和删除要注意的问题
  • 原文地址:https://www.cnblogs.com/lifehappy/p/13051658.html
Copyright © 2011-2022 走看看