2020ccpc綿陽 J題 區間染色
阿新 • • 發佈:2020-11-01
題面
給n個點長度為t,亮度為x的長燈,鋪在長度為m 的路上,每(0~t)* k(k=0,2,4……)的位置鋪燈,問最好路的亮度情況。
樣例
2 8
1 1
2 2
輸出
2 2 1 0 2 2 1 0
思路
並查集染色問題。先對燈種類離散化,找到每個t的最大值x,然後按照x的大小從大到小排序
迴圈區間(0~t)* k(k=0,2,4……)把每個點併到(0~t)* k + 1
程式碼
#include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define lson(x) x<<1 #define rson(x) x<<1|1 using namespace std; const int N=1e5+10; struct node{ int t,x; friend bool operator<(const node a,const node b){ if(a.x==b.x){ return a.t<b.t; } return a.x>b.x; } }a[N]; int liang[N]; int f[N]; int F(int x){ return f[x]==x?x:f[x]=F(f[x]); } void mere(int x,int y){ int xx=F(x),yy=F(y); if(xx!=yy){ f[xx]=f[yy]; } } inline int read(){ char c; int ret=0; while((c=getchar())<'0' || c>'9'); while(c>='0' && c<='9'){ ret=ret*10+(c-'0'),c=getchar(); } return ret; } int main(){ int T,ca=1; scanf("%d",&T); while(T--){ int n,m; scanf("%d%d",&n,&m); // n=read();m=read(); map<int,int>mp; int cnt=1; for(int i=1;i<=m+1;i++){ liang[i]=0;f[i]=i; } for(int i=0;i<n;i++){ int t,x; scanf("%d%d",&t,&x); // t=read();x=read(); if(mp[t]==0){ mp[t]=cnt++; a[mp[t]].t=t;a[mp[t]].x=x; } else{ a[mp[t]].x=max(a[mp[t]].x,x); } } sort(a+1,a+cnt); for(int i=1;i<cnt;i++){ int t=a[i].t,x=a[i].x; for(int j=1;j<=m;j+=2*t){ //cout<<j<<endl; int l=F(j),r=min(j+t-1,m); while(l<=r){ liang[l]=x; mere(l,r+1); l=F(l+1); } } if(F(1)==m+1){break;} } printf("Case #%d: ",ca++); for(int i=1;i<=m;i++){ printf(i==m?"%d\n":"%d ",liang[i]); } } return 0; }
ccpc為什麼現在題目這麼難,直接暴露了,我資料結構和博弈垃圾成fw,學了圖論什麼都沒用。。水哥線段樹寫出了,到時候把線段樹的寫法學一下