有\(k\)種顏色,給你\(n\)個區間段,選擇一種合適的方案給每一個區間段染色,使得最終染色次數等於\(k\)次的長度和最大。node
將左右端點放在一塊兒排序,可是標記出它是左端點,仍是右端點,而且記錄每一個端點屬於第幾個區間,排序後,對於每一個左端點,從未使用過的顏色中選一個染色此區間,若連續染色超過\(k\)次,則多於的區間放入棧中備用,當某次染色小於\(k\)次時拿出來染色。當遇到右端點時,若這段區間染過色,則將此顏色收回,若沒染過色,隨意染色便可。ios
最重要的,必定要按格式輸出,末尾不能有空格c++
/* * @Author: _Simon_ * @Date: 2019-10-30 10:44:14 * @Last Modified by: Simon * @Last Modified time: 2019-10-30 10:44:14 */ #include<bits/stdc++.h> using namespace std; #define int long long #define maxn 200005 #define INF 0x3f3f3f3f struct node{ int first,second,ord; node(){} node(int first,int second,int ord):first(first),second(second),ord(ord){} bool operator <(const node&a) const{ if(first==a.first) return second<a.second; return first<a.first; } }; vector<node>a; int ans[maxn]; signed main(){ ios::sync_with_stdio(false); cin.tie(0); int T;cin>>T; while(T--){ memset(ans,0,sizeof(ans)); a.clear(); int n,k;cin>>n>>k; for(int i=1;i<=n;i++){ int l,r;cin>>l>>r; a.push_back({l,1,i}); a.push_back({r,-1,i}); } sort(a.begin(),a.end()); queue<int>q;stack<int>st; for(int i=1;i<=k;i++) q.push(i); int tmp=0,pret=0,preidx=0; for(int i=0;i<a.size();i++){ if(a[i].second>0){ //左端點 if(tmp<k){ //連續染色小於k次 tmp++; ans[a[i].ord]=q.front();q.pop(); //從未染色的顏色中選出一個染色 }else{ st.push(a[i].ord); //染色大於k次,備用 } }else{ //右端點 if(ans[a[i].ord]){ //若所在區間染過色 q.push(ans[a[i].ord]); //收回顏色 tmp--; }else{ ans[a[i].ord]=1; //不然隨意染色 } } if(i+1<a.size()&&a[i].first==a[i+1].first) continue; //一樣端點一塊兒處理 while(tmp<k){ //若染色小於k次,從備用端點中選取 while(!st.empty()&&ans[st.top()]) st.pop(); if(st.empty()) break; tmp++; ans[st.top()]=q.front();st.pop();q.pop(); } if(pret>=k) ans[0]+=a[i].first-preidx; //計算染色次數等於k次的長度 preidx=a[i].first;pret=tmp; } cout<<ans[0]<<endl; for(int i=1;i<=n;i++) cout<<ans[i]<<" \n"[i==n]; //按格式輸出 } return 0; }