2020CCPC-绵阳站-Joy of Handcraft (并查集分块思想)

7-10 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
 Sample Output
Case #1: 2 2 1
Case #2: 3 3 2 0 3
Case #3: 3 0 3
题目大意:
  每盏灯从0秒开始亮t秒,关t秒,灯开着的时候亮度为x。问1~m每秒灯最大亮度是多少。
分析:x最大的灯亮的时候,就不需要看其他的灯了,所以按x从大到小覆盖区间1~m,已经覆盖的就不用管了,
如果已经覆盖的能直接跳过,就能节省出很多时间。所以可以用类似并查集来跳过已覆盖的。
  当ans[i]=0的时候说明没有覆盖,用当前x覆盖该区间,用fa[i-1]=i可以把前面已覆盖的和当前已覆盖的结合
起来,就算i前一个区间没被覆盖也没关系,因为只有被覆盖的地方才用并查集的find跳到下一个。
  当ans[i]!=0说明已覆盖,就可以i=find(i)跳到没覆盖的地方了。
#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;
}

 




posted on 2020-11-07 23:36  Aminers  阅读(245)  评论(0编辑  收藏  举报

导航