专栏文章
题解:P14507 缺零分治 mexdnc
P14507题解参与者 8已保存评论 7
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @min7t78h
- 此快照首次捕获于
- 2025/12/01 21:58 3 个月前
- 此快照最后确认于
- 2025/12/01 21:58 3 个月前
思路
先考虑朴素做法,那么先处理出每个 mex 最多有多少个,显然我们只关注一个从 至 的一段连续的数,从大到小考虑,每个数能取就取,一定最优,细节不是很多。复杂度 。
考虑优化,我们可以预处理出 表示把大于等于 的数能选的全选上的和,那么每次只需要二分查找第一个大于等于 的 ,这时把若干 变成更小的数即可使和为 。
复杂度
CPP#include<bits/stdc++.h>
using namespace std;
#define int long long
int read()
{
int num = 0,f = 1;
char c = getchar();
while(!isdigit(c))
{
if(c == '-')
{
f = -1;
}
c = getchar();
}
while(isdigit(c))
{
num = num * 10 + (c - '0');
c = getchar();
}
return num * f;
}
struct node
{
int a,b;
} a[110000];
int cnt[110000],sum[110000];
signed main()
{
int T = read();
while(T--)
{
int n = read(),q = read();
for(int i = 1;i <= n;i++)
{
a[i].a = read();
a[i].b = read();
}
cnt[0] = 2e9;
int maxn = 0;
for(int i = 1;i <= n;i++)
{
if(a[i].a == i - 1)
{
cnt[i] = min(cnt[i - 1],a[i].b);
}
else
{
cnt[i] = 0;
}
if(cnt[i])
{
maxn = max(maxn,i);
}
}
cnt[maxn + 1] = 0;
for(int i = maxn;i >= 1;i--)
{
sum[maxn - i + 1] = sum[maxn - i] + (cnt[i] - cnt[i + 1]) * i;
}
//cout << maxn << endl;
while(q--)
{
int m = read();
if(m == 0)
{
if(a[1].a == 0)
{
cout << -1 << '\n';
}
else
{
cout << 1 << '\n';
}
continue;
}
int t = lower_bound(sum + 1,sum + maxn + 1,m) - sum - 1;
if(t == maxn)
{
cout << -1 << '\n';
continue;
}
m -= sum[t];
int k = maxn - t;
int cntt = (m - 1) / k;
//cout << cntt << endl;
if(m < k && t == 0)
{
cout << 2 << '\n';
}
else
{
cout << cnt[k + 1] + cntt + 1 << '\n';
}
}
}
return 0;
}
相关推荐
评论
共 7 条评论,欢迎与作者交流。
正在加载评论...