2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛)Monopoly
发布时间
阅读量:
阅读量
HDU 7130 Monopoly
对于题目来说我们要有
一个前缀和sum[i]:代表每走一步能得到的价值
一个总和S:走完一轮后的总和
一个set
一个map
一个map

对于每次询问的数x
对于S是0的情况:我们用map存下每个数的对应的位置直接找即可(模的话会出错)
对于S不是0的情况:
首先看x是不是
是0直接输出0
不是0再看x\%S这个模数集合中是否有元素的存在如果没有则输出-1
否则在这个模数集合中找到大于x或者小于x离他最近的那个sum[i](找法与sum[i]正负有关)
然后用|x-sum[i]|/S*n(循环次数)+ \_pos[sum[i]](数对应的位置)
对于模数集合set可自动排序和去重然后二分查找
利用map离散化和映射
#include<bits/stdc++.h>
#include <unordered_map>
using namespace std;
template<class...Args>
void debug(Args... args) {//Parameter pack
auto tmp = { (cout << args << ' ', 0)... };
cout << "\n";
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>pll;
typedef pair<int, int>pii;
const ll N = 5e5 + 5;
const ll INF = 0x7fffffff;
const ll MOD = 998244353;
ll sum[N];
set<ll>bucket[N];//桶(存放模数相同的数的集合)
map<ll, ll>_hash;//模数转化为桶的位置(离散化)
map<ll, ll>_pos;//值转换为位置(保存最强面的位置即可)
void init() {
for (auto it = _hash.begin(); it != _hash.end(); it++)bucket[it->second].clear();
memset(sum, 0, sizeof sum);
_hash.clear();
_pos.clear();
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--) {
init();
int n, m;
cin >> n >> m;
ll S = 0;
for (int i = 1; i <= n; i++) {
cin >> sum[i];
S += sum[i];
sum[i] += sum[i - 1];//前缀和
if (_pos.count(sum[i]) == 0) _pos[sum[i]] = i;//存下数对应的地址
}
if (S != 0) {
ll cnt = 0;
for (int i = 1; i <= n; i++) {
ll tt = ((sum[i] % S) + S) % S;
if (_hash[tt] == 0) _hash[tt] = ++cnt;//离散化
bucket[_hash[tt]].insert(sum[i]);//存入对应的集合中去
}
while (m--) {
ll x;
cin >> x;
ll tt = ((x % S) + S) % S;
if (x == 0) cout << 0 << "\n";
else if (bucket[_hash[tt]].size() == 0) cout << -1 << "\n";
else {
if (S > 0) {
set<ll>::iterator it = bucket[_hash[tt]].upper_bound(x);
if (it == bucket[_hash[tt]].begin())cout << -1 << "\n";
else {
it--;
cout << (x - *it) / S * n + _pos[*it] << "\n";
}
}
else {
set<ll>::iterator it = bucket[_hash[tt]].lower_bound(x);
if (it == bucket[_hash[tt]].end())cout << -1 << "\n";
else {
cout << (x - *it) / S * n + _pos[*it] << "\n";
}
}
}
}
}
else {
while (m--) {
int x;
cin >> x;
if (x == 0)cout << 0 << "\n";
else {
if (_pos[x] == 0)cout << -1 << "\n";
else cout << _pos[x] << "\n";
}
}
}
}
return 0;
}
全部评论 (0)
还没有任何评论哟~
