2020 CCPC 绵阳站 :J. Joy of Handcraft

J. Joy of Handcraft

题目大意:

给你n盏灯,每盏灯亮的周期为ti( 1 ~ ti 亮,ti+1 ~ 2ti灭,然后循环往复),每盏灯的亮度为 xi。问你 1~m 中每一秒最亮的灯的亮度。

思路:

对于相同周期的灯泡,我们保留最亮的那一盏就行,这样最多也只有n种周期,把下放的点加起来,发现是调和级数,复杂度是log级别的。然后用线段树正常维护和修改线段树的区间最大值即可。最后算法的复杂度为 nlogmlogm。

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
struct Node
{
    
    
    int ti;
    int xi;
}node[N];
struct Tree
{
    
    
    int l,r,maxn;
    int lazy;
}tr[N*4];
int vis[N],res[N];
bool cmp(Node a,Node b)
{
    
    
    return a.xi>b.xi;
}
void pushup(int k)
{
    
    
    tr[k].maxn=max(tr[k<<1].maxn,tr[k<<1|1].maxn);
}
void pushdown(int k)
{
    
    
    tr[k<<1].lazy=max(tr[k<<1].lazy,tr[k].lazy);
    tr[k<<1|1].lazy=max(tr[k<<1|1].lazy,tr[k].lazy);
    tr[k<<1|1].maxn=max(tr[k<<1|1].maxn,tr[k].maxn);
    tr[k<<1].maxn=max(tr[k<<1].maxn,tr[k].maxn);
    tr[k].lazy=0;
}
void build(int k,int l,int r)
{
    
    
    tr[k].l=l,tr[k].r=r;
    if(l==r)
    {
    
    
        tr[k].lazy=0;
        tr[k].maxn=0;
        return ;
    }
    int mid=(l+r)/2;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    pushup(k);
}
void modify(int k,int L,int R,int x)
{
    
    
    if(L<=tr[k].l&&tr[k].r<=R)
    {
    
    
        tr[k].lazy=max(tr[k].lazy,x);
        tr[k].maxn=max(tr[k].maxn,x);
        return ;
    }
    pushdown(k);
    int mid=(tr[k].l+tr[k].r)/2;
    if(L<=mid) modify(k<<1,L,R,x);
    if(R>mid) modify(k<<1|1,L,R,x);
}
void query(int k,int idx)
{
    
    
    if(tr[k].lazy) pushdown(k);
    if(tr[k].l==idx&&tr[k].r==idx)
    {
    
    
        res[idx]=tr[k].maxn;
        return ;
    }
    int mid=(tr[k].l+tr[k].r)/2;
    if(idx<=mid) query(k<<1,idx);
    else query(k<<1|1,idx);
}
int main()
{
    
    
    int t;
    scanf("%d",&t);
    for(int j=1;j<=t;j++)
    {
    
    
        int n,m;
        scanf("%d%d",&n,&m);
        memset(vis,0,sizeof(vis));
        build(1,1,m);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&node[i].ti,&node[i].xi);
        sort(node+1,node+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
    
    
            if(vis[node[i].ti]) continue;
            vis[node[i].ti]=1;
            int k=0;
            while(k*node[i].ti+1<=m)
            {
    
    
                int st=k*node[i].ti+1;
                int ed=(k+1)*node[i].ti;
                k=k+2;
                modify(1,st,min(ed,m),node[i].xi);
            }
        }
        for(int i=1;i<=m;i++) query(1,i);
        printf("Case #%d: ",j);
        for(int i=1;i<=m;i++)
        {
    
    
            if(i==m) printf("%d",res[i]);
            else printf("%d ",res[i]);
        }
        printf("\n");
    }
    //system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Stevenwuxu/article/details/110099285