原题链接https://ac.nowcoder.com/acm/contest/11253/K
如果当前点的b比下标还大或者b值的增长速度大于下标的增长速度就一定无解
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 10;
PII vis[N];
bool st[N]; //记录是否存在约束
int a[N];
int b[N];
int n, k;
bool cmp(PII x, PII y)
{
int fp = x.first, fv = x.second;
int np = y.first, nv = y.second;
if (fv == nv)
return fp > np;
return fv < nv;
}
bool check()
{
for (int i = 0; i < k; i++)
{
int fp = vis[i].first, fv = vis[i].second;
int np = vis[i + 1].first, nv = vis[i + 1].second;
if (fp < fv)
return 1;
if (i == k - 1)
break;
if (fv + np - fp < nv)
return 1;
}
return 0;
}
void solve()
{
//由后面的约束推知前面点的约束
for (int i = 0; i < k; i++)
{
int fp = vis[i].first, fv = vis[i].second;
int t = 1;
for (int j = fp - 1; j >= 1 && !st[j]; j--)
b[j] = max(fv - t,1), t++;
}
for (int i = 1; i <= n; i++)
if (!b[i])
b[i] = b[i - 1];
memset(vis, 0, sizeof vis);
//当b[i]!=b[j]的优先填充较小的数
//当b[i]=b[j]时将最小的数填充到数组下标较大
for (int i = 1; i <= n; i++)
vis[i] = {i, b[i]};
sort(vis + 1, vis + n + 1, cmp);
for (int i = 1; i <= n; i++)
{
int pos = vis[i].first;
a[pos] = i;
}
for (int i = 1; i <= n; i++)
printf("%d ",a[i]);
cout<<endl;
}
int main()
{
cin >> n >> k;
for (int i = 0; i < k; i++)
{
int x, y;
cin >> x >> y;
vis[i] = {x, y};
st[x] = 1;
b[x] = y;
}
if (check())
cout<<"-1"<<endl;
else
solve();
return 0;
}