PS:思路巨明显,就是代码写不出,总想着一次更新一条线段。这里用一个set,存的是当前能用的数的。怎么去更新set,记录上一个区间的左右端点 l , r ,然后类似于莫队的写法。。。。看代码吧。注意上一个区间和当前区间没有公共端点时要特判!!!,也就是代码中的 if 语句 。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<bitset> #include<vector> #include<set> #define ll long long #define P pair<int, int> #define PP pair<int,pair<int, int>> #define pb push_back #define pp pop_back #define lson root << 1 #define INF (int)2e9 + 7 #define rson root << 1 | 1 #define LINF (unsigned long long int)1e18 #define mem(arry, in) memset(arry, in, sizeof(arry)) using namespace std; const int maxn = 100005; int T, n, m, res[maxn]; P p[maxn]; int main() { cin >> T; while(T--) { mem(res, 0); scanf("%d %d", &n, &m); for(int i = 1; i <= m; i++) scanf("%d %d", &p[i].first, &p[i].second); sort(p + 1, p + m + 1); set<int> unused; for(int i = 1; i <= n; i++) unused.insert(i); int l = p[1].first, r = p[1].second; int t = 0; for(int i = l; i <= r; i++) { res[i] = ++t; unused.erase(t); } for(int i = 2; i <= m; i++) { int tl = p[i].first; int tr = p[i].second; if(tr <= r) continue; while(l < tl) { if(res[l]) unused.insert(res[l]); l++; } while(r < tr) { ++r; if(r >= tl) { res[r] = *unused.begin(); unused.erase(res[r]); } } } for(int i = 1; i <= n; i++) printf("%d%c", (res[i] == 0 ? 1 : res[i]), (i == n ? ‘\n‘ : ‘ ‘)); } return 0; }
原文地址:https://www.cnblogs.com/zgglj-com/p/9363166.html
时间: 2024-10-21 22:06:09