HDU6301 Distinct Values (多校第一場1004) (貪心)

ACMerszl發表於2018-09-09

Distinct Values

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4869    Accepted Submission(s): 1659

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 (li<jr), aiaj holds.
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 (1n,m105) — the length of the array and the number of facts. Each of the next m lines contains two integers li and ri (1lirin).

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
 
 
給出q個[l,r]   要求[l,r]範圍內數字不重複 ,求字典序最小的滿足q個要求的序列。
 
 
首先預處理出來覆蓋每一個點的最左端點pre[i] ,用p從1開始 和  pre[i]比較,(因為當前區間是[pre[i], i],  上個區間是 [p, i-1] )  如果 p < pre[i] , 就把[p, pre[i]-1] 的數都釋放了(插入set還能用)如果 p > pre[i], 直接取set.begin().
 
 
 
 
 1 // D
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 #define rep(i,a,n) for (int i=a;i<n;i++)
 5 #define per(i,a,n) for (int i=n-1;i>=a;i--)
 6 #define pb push_back
 7 #define mp make_pair
 8 #define all(x) (x).begin(),(x).end()
 9 #define fi first
10 #define se second
11 #define SZ(x) ((int)(x).size())
12 typedef vector<int> VI;
13 typedef long long ll;
14 typedef pair<int,int> PII;
15 const ll mod=1000000007;
16 ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
17 ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
18 // head
19 
20 const int N=101000;
21 int _,n,m,pre[N],l,r,ret[N];//pre維護覆蓋i的最左端點 
22 int main() {
23     for (scanf("%d",&_);_;_--) {
24         scanf("%d%d",&n,&m);
25         rep(i,1,n+1) pre[i]=i;
26         rep(i,0,m) {
27             scanf("%d%d",&l,&r);
28             pre[r]=min(pre[r],l);
29         per(i,1,n) pre[i]=min(pre[i],pre[i+1]);//pre[i]是pre[i]和pre[i+1]的最小值
30         int pl=1;//從1開始 和覆蓋每個點的最左端點pre[i]比較
31         set<int> val;
32         rep(i,1,n+1) val.insert(i);//維護最小可用的數
33         rep(i,1,n+1) {
34             //上個 [pl, i-1]
35 
36             //當前 [pre[i], i]
37             while (pl<pre[i]) {//小於pre[i]的點的值  插入set
38                 val.insert(ret[pl]);
39                 pl++;
40             }
41             ret[i]=*val.begin();//不小於直接取最小的數放進去
42             val.erase(ret[i]);//刪除剛放入的數
43         }
44         rep(i,1,n+1) printf("%d%c",ret[i]," 
"[i==n]);
45     }
46 }

 

 

相關文章