Distinct Values
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2298 Accepted Submission(s): 740
Problem Description
Chiaki has an array of n positive integers. You are told some facts about the array: for every two elements ai and aj in the subarray al..r (l≤i<j≤r), ai≠ajholds.
Chiaki would like to find a lexicographically minimal array which meets the facts.
Chiaki would like to find a lexicographically minimal array which meets the facts.
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains two integers n and m (1≤n,m≤105) -- the length of the array and the number of facts. Each of the next m lines contains two integers li and ri (1≤li≤ri≤n).
It is guaranteed that neither the sum of all n nor the sum of all m exceeds 106.
The first line contains two integers n and m (1≤n,m≤105) -- the length of the array and the number of facts. Each of the next m lines contains two integers li and ri (1≤li≤ri≤n).
It is guaranteed that neither the sum of all n nor the sum of all m exceeds 106.
Output
For each test case, output n integers denoting the lexicographically minimal array. Integers should be separated by a single space, and no extra spaces are allowed at the end of lines.
Sample Input
3
2 1
1 2
4 2
1 2
3 4
5 2
1 3
2 4
Sample Output
1 2
1 2 1 2
1 2 3 1 1
Source
思路:
打的好菜啊。。最后看了学长的思路才写出来了,完全没想到线段树的思路aaaaa。
这道题难点就是在处理之前区间与当前区间重叠区间的数。。。
线段树写法就是将现在这个区间的赋值作为下标存进线段树+1,当访问下一个区间时将重叠部分之前的部分全部变为0,
这样重叠部分的下标依旧是1然后求区间mex依此赋值,并依此更新下下标(也就是把访问过的标为1),讲的有点乱,看下代码把。
实现代码:
#include<bits/stdc++.h> using namespace std; const int M = 1e5+10; int sum[M<<2]; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid int m = (l + r) >> 1 void pushup(int rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void update(int p,int c,int l,int r,int rt){ if(l == r){ sum[rt] += c; return ; } mid; if(p <= m) update(p,c,lson); else update(p,c,rson); pushup(rt); } void build(int l,int r,int rt){ if(l == r){ sum[rt] = 0; return ; } mid; build(lson); build(rson); pushup(rt); } int query(int l,int r,int rt){ if(l == r){ return l; } mid; if(sum[rt<<1] < m-l+1) query(lson); else query(rson); } struct node{ int l,r; }a[M]; int b[M]; bool cmp(node a,node b){ if(a.l == b.l) return a.r > b.r; return a.l < b.l; } int main() { int t,n,m; while(scanf("%d",&t)!=EOF){ while(t--){ scanf("%d%d",&n,&m); for(int i = 1;i <= m;i ++){ scanf("%d%d",&a[i].l,&a[i].r); } sort(a+1,a+1+m,cmp); build(1,n,1); memset(b,0,sizeof(b)); int L = 0,R = 0,u = 0; for(int i = 1;i <= m;i ++){ if(a[i].r < R+1) continue; for(int j = L;j < a[i].l;j ++){ if(b[j] == 0) continue; update(b[j],-1,1,n,1); } if(R >= a[i].l) u = R+1; else u = a[i].l; for(int j = u;j <= a[i].r;j ++){ int cnt = query(1,n,1); b[j] = cnt; update(cnt,1,1,n,1); } L = a[i].l; R = a[i].r; } for(int i = 1;i <= n;i ++){ if(b[i]==0) printf("1"); else printf("%d",b[i]); if(i == n) printf(" "); else printf(" "); } } } return 0; }