题目:给m个区间[li,ri],要构造一个长度为n的串,每个区间内的数不能有相同的,且整个串的字典序最小
思路:记录每个区间的左端点,让右端点等于左端点,然后倒着维护一下,保证per[i-1]<=pre[i]。然后将每个区间可以放的数放在set中,从左到右填充即可。
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
int ret[100005];
int main()
{
int n,m,_,l,r,t,pre[100005];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
rep(i,1,n+1) pre[i]=i;//先让每个点的端点为本身
rep(i,0,m) {
scanf("%d%d",&l,&r);
pre[r]=min(pre[r],l);//记录一下[l,r]这个区间
}
per(i,1,n) pre[i]=min(pre[i],pre[i+1]);//倒着维护一下
set<int> val;
rep(i,1,n+1) val.insert(i);//假设每一个位置为他本身
int pl=1;
rep(i,1,n+1)
{
while(pl<pre[i])//更新从pl->pre[i]这个区间可以放得数字
{
val.insert(ret[pl]);
pl++;
}
ret[i]=*val.begin();
val.erase(ret[i]);
}
rep(i,1,n+1) printf("%d%c",ret[i]," \n"[i==n]);//[i==n]下面讲解
}
return 0;
}
printf("%c"," \n"[i==n]);
看为数组,i==n为逻辑判断,即只有当i==n时输出“\n”,否则输出" "。