2020CCPC-绵阳站-Joy of Handcraft (并查集分块思想)
Little Horse always does some handcrafts, which is full of joy. This time, he builds a circuit that can turn on and off the bulbs periodically.
There are n bulbs in the circuit, the i-th of which has a period ti and a luminance xi. Formally, the i-th bulb will be turned on from the (-th second to the (-th second, and it will be turned off from the (-th second to the (-th second, , When the i-th bulb is on, its luminance will be xi, otherwise its luminance will be 0.
Now, Little Horse wants to know, for each second from the first second to the m-th second, what's the maximum luminance among all the bulbs.
Input
The first line of the input contains an integer T (1) − the number of test cases.
The first line of each test case contains two integers , (1) − the number of bulbs, and the number of integers you need to output. The sum of n and the sum of m will not exceed 2.
Then in the next n lines, the i-th line contains two integers , (1) − the period and the luminance of the i-th bulb.
Output
The x-th test case begins with Case #x:, and there follow m integers. The i-th integer indicates the maximum luminance among all the bulbs in the i-th second. If no bulb is on in the i-th second, output 0.
Sample Input
3
2 3
1 1
2 2
2 5
1 2
2 3
3 3
1 1
1 2
1 3
Case #1: 2 2 1
Case #2: 3 3 2 0 3
Case #3: 3 0 3
#include<bits/stdc++.h> #include<ext/rope> //#include<hash_map> #define sd(x) scanf("%d",&x) #define lsd(x) scanf("%lld",&x) #define ms(x,y) memset(x,y,sizeof x) #define fu(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define all(a) a.begin(),a.end() using namespace std; using namespace __gnu_cxx; typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int maxn=1e5+91; const int mod=1e9+7; const int INF=1e9+7; const double pi=acos(-1); struct od { int t,x; bool operator<(const od &a)const { if(x==a.x) return t<a.t; return x>a.x; } }a[maxn]; int n,m,ans[maxn],fa[maxn]; bool used[maxn]; int find(int i) { if(i==fa[i]) return i; return fa[i]=find(fa[i]); } void solve() { ms(used,0); cin>>n>>m; fu(i,1,n) { cin>>a[i].t>>a[i].x; } fu(i,1,m) ans[i]=0,fa[i]=i; sort(a+1,a+n+1); fu(i,1,n) { int t=a[i].t;//t相同的已经被覆盖了,直接跳过 if(used[t]) continue; used[t]=1; for(int k=1;k<=m;k+=2*t) { //枚举每个t的起点k for(int j=k;j<k+t&&j<=m;j++) { //并查集合并主要是合并已覆盖的 if(ans[j]==0) ans[j]=a[i].x,fa[j-1]=j; else j=find(j); } } } fu(i,1,m) { printf("%d%c",ans[i],i==m?'\n':' '); } } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0);//cout和printf不要不要不要连用!! int t;cin>>t; fu(i,1,t) { printf("Case #%d: ",i); solve(); } return 0; }