B 赛博算命 (模拟)
B 赛博算命
Description:
- 假设第一轮比赛共有 $ k \geq 2 $名选手,有以下规定:
- 如果存在整数 \(n\) 使得 \(k =2^n\),那么编号为 \(1\) 的选手对战编号为 \(2^n\) 的选手,那么编号为 \(2\) 的选手对战编号为 \(2^n-1\) 的选手,以此类推,没有选手轮空,这一场比赛结束后,只剩下 \(2^{n-1}\) 个选手。
- 如果存在整数 \(n\) 使得 \(2^{n-1} < k < 2^n\),在保证第一轮结束后还剩下 \(2^{n-1}\) 个选手的前提下,编号为 \(1\) 的选手对战编号为 \(k\) 的选手,编号为 \(2\) 的选手对战编号为 \(k-1\) 的选手,以此类推,剩下一些编号中间的选手轮空,如果轮空,则认为对手的编号为 \(k+1\) 号。
- 已知自己和队友们的编号,求对手的编号的乘积(结果对\(10^9+7\)取模)
Constraints:
- \(1 \leq q \leq 10^6, 2 \leq k \leq 10^9, q\leq k\)
Analysis:
- 模拟题
Solution:
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5+5;
const int maxm = 1e6+5;
ll qpow(ll a,ll n) {
ll ans = 1;
while(n) {
if(n & 1) ans *= a;
a *= a;
n >>= 1;
}
return ans;
}
map<int,ll> mp; //记录幂指数
vector<int> v;
int main() {
for(int i=0;i<31;i++) mp[i] = qpow(2,i); //初始化
int n,k; cin >> n >> k;
for(int i=0;i<n;i++) {
int id; cin >> id;
v.push_back(id);
}
ll ans = 1;
for(int i=0;i<31;i++) {
if(k == mp[i]) {
for(int j=0;j<v.size();j++) {
ans = ans * (k-v[j]+1) % mod;
}
break;
}
if(mp[i] < k && k < mp[i+1]) {
for(int j=0;j<v.size();j++) {
if(v[j] >= mp[i]+1 || v[j] <= k-mp[i]) ans = ans * (k+1-v[j]) % mod;
else ans = ans * (k+1) % mod;
}
break;
}
}
cout << ans << endl;
return 0;
}
本文来自博客园,作者:Trilliverse,转载请注明原文链接:https://www.cnblogs.com/Trilliverse/p/17826212.html