求一個長度爲n的數列, 給出m個區間,這m個區間各自區間內的數不同
當時比賽打完3題後稍微看了一下這題想了幾分鐘不是很容易就丟了。。比完想補這題想了一個垃圾做法複雜度有點高不敢寫,於是面向標程編程了。。。大佬的做法真的清奇唉慢慢學吧
預處理一下用一個數組保存以這個點爲起點的查詢的最大的R的位置last[l] = max(last[l],r) (這裏相當於去掉了完全包含在大區間裏的小區間,因爲包含在大區間裏的小區間是完全沒用的直接丟掉),沒有查詢的話就last[i] = i
唉思路不是很好用語言描述(大佬的做法真的太神了。。)直接看代碼更容易懂。。。。
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <queue>
using namespace std;
const int mx = 1e5+7;
int last[mx];
int ans[mx];
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int n, m;
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; i++)
last[i] = i;
int l, r;
for (int i = 1; i <= m; i++)
{
scanf("%d%d",&l,&r);
last[l] = max(last[l],r);
}
set <int> vis;
for (int i = 1; i <= n; i++) vis.insert(i);
l = 1, r = 0;
for (int i = 1; i <= n; i++)
{
if (r > last[i]) continue;
while (l < i)
{
vis.insert(ans[l]);
l++;
}
while (r < last[i])
{
ans[++r] = *vis.begin();
vis.erase(ans[r]);
}
}
for (int i = 1; i <= n; i++)
printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}