• E. Johnny and Grandmaster


    https://codeforces.com/contest/1362/problem/E

    题目意思就是给一个长度为n的序列k , 然后呢要求将这些数分为两个集合A、B,使得两个集合差值的绝对值最小,也就是$$min|sum_{iin A}p^{k[i]} - sum_{jin B} p^{k[j]}| $$

    做法就是将这个题目呢看成P进制表示,(p^{k[i]})也就是第k[i]为上面是1,
    在进制表示里面,我们从左到右下标增加1 . 2 . 3 . 4 . 5...... n
    策略 :

    1. 按照k值降序排列
    2. (p^{k[i]} >= p^{k[i + 1]} + p^{k[i + 2]} + ... + p ^ {k[j]}) , 在进制里面我们一定可以得到(sum_{j < i}p^{j} = p^{i}) , 比如(2^{3} = 2^{2} + 2 ^ {2})
    3. (i = 1) 开始拿,用ans表示两个插值,因为k降序, 所以再根据第二个条件,对于当前的k[i]如果是加上这个贡献 (ans += p^{k[i]}), 那么后面肯定要减掉一堆k[j] , (ans -= sum_{j > i}p^{k[j]}) ,直到ans = 0 ;
    4. 当ans再次等于0,重复第三个过程
    5. 还有就是ans = 0 , 因为是取了mod之后的,所以这个ans有可能是mod 的倍数,那么要判断ans是否真正为0 , 只需要简单的再搞一个res % Mod , 和 ans % mod 一样 , 只要这两个ans 和 res 同时为 0 , 就表示ans为0,而不是ans 是 mod 的倍数 , 就像一个人说了不算, 两个才有正确性
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <unordered_map>
    #include <vector>
    #include <map>
    #include <list>
    #include <queue>
    #include <cstring>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <set>
    #pragma GCC optimize(3 , "Ofast" , "inline")
    using namespace std ;
    #define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
    #define x first
    #define y second
    typedef long long ll ;
    const double esp = 1e-6 , pi = acos(-1) ;
    typedef pair<int , int> PII ;
    const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7 , Mod = 1e9 + 3;
    ll in()
    {
      ll x = 0 , f = 1 ;
      char ch = getchar() ;
      while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
      while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
      return x * f ;
    }
    ll qmi(ll a , ll b , ll mod)
    {
      ll res = 1 ;
      while(b)
       {
         if(b & 1) res = res * a % mod ;
         a = a * a % mod ;
         b >>= 1;
       }
       return res ;
    }
    ll k[N] ;
    void work()
    {
      int n = in() , p = in() ;
      for(int i = 1; i <= n ;i ++ ) k[i] = in() ;
      if(p == 1)
       {
         cout << (n % 2) << endl ;
         return ;
       }
      sort(k + 1 , k + n + 1) ;
      reverse(k + 1 ,k + n + 1) ;
      ll res = 0 , ans = 0 ;
      for(int i = 1; i <= n ;i ++ )
         if(!ans && !res) ans += qmi(p , k[i] , mod) , res += qmi(p , k[i] , Mod) ;
         else
           ans = ((ans - qmi(p , k[i] , mod))% mod + mod) % mod ,
           res = ((res - qmi(p , k[i] , Mod))% Mod + Mod) % Mod ;
      cout << ans << endl ;
      return ;
    
    }
    int main()
    {
      int n = in() ;
      while(n --) work() ;
      return 0 ;
    }
    /*
    */
    
    
  • 相关阅读:
    POJ2481:Cows(树状数组)
    Go语言用堆排序的方法进行一千万个int随机数排序.
    【一】注入框架RoboGuice使用:(A brief example of what RoboGuice does)
    POJ3067:Japan(树状数组求逆序对)
    Android开发之ListView实现不同品种分类分隔栏的效果(非ExpandableListView实现)
    躁动不安的const
    JAVA实现RSA加密解密 非对称算法
    Cocos2d坐标系具体解释
    leetcode_Product of Array Except Self
    IIS2008配置URlRewriter
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/13051426.html
Copyright © 2020-2023  润新知