https://codeforces.com/contest/1362/problem/E
题目意思就是给一个长度为n的序列k , 然后呢要求将这些数分为两个集合A、B,使得两个集合差值的绝对值最小,也就是$$\min|\sum_{i\in A}p^{k[i]} - \sum_{j\in B} p^{k[j]}| $$
做法就是将这个题目呢看成P进制表示,\(p^{k[i]}\)也就是第k[i]为上面是1,
在进制表示里面,我们从左到右下标增加1 . 2 . 3 . 4 . 5...... n
策略 :
#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 ;
}
/*
*/
原文:https://www.cnblogs.com/spnooyseed/p/13051426.html