洛谷 省选营题目 过年

Posted Driver_Lao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 省选营题目 过年相关的知识,希望对你有一定的参考价值。

【题解】

  差分+扫描线+权值线段树。

  我们先把区间操作差分,变成2*m个点操作,然后按照位置对操作进行排序。接着按顺序处理每个位置的答案,如果当前位置有操作,就先在权值线段树上修改,再统计当前点的答案。

  要注意的是,题目问的是出现次数最多的礼物的编号,所以权值线段树要维护的不仅是最大值,还有最大值的位置。

#include<cstdio>
#include<algorithm>
#define rg register
#define N 400010
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((a[u].l+a[u].r)>>1)
using namespace std;
int n,m,pos,cnt[N];
struct tree{
    int l,r,mx;
}a[N];
struct rec{
    int pos,k,type;
}r[N];
inline int read(){
    int k=0,f=1; char c=getchar();
    while(c<\'0\'||c>\'9\')c==\'-\'&&(f=-1),c=getchar();
    while(\'0\'<=c&&c<=\'9\')k=k*10+c-\'0\',c=getchar();
    return k*f;
}
inline int max(int x,int y){return x>y?x:y;}
inline int cmp(rec a,rec b){return a.pos<b.pos;}
void build(int u,int l,int r){
    a[u].l=l; a[u].r=r;
    if(l<r) build(ls,l,mid),build(rs,mid+1,r);
}
void add(int u,int pos,int del){
    if(a[u].l==a[u].r) a[u].mx+=del;
    else{
        if(pos<=mid) add(ls,pos,del);
        else add(rs,pos,del);
        a[u].mx=max(a[ls].mx,a[rs].mx);
    }
}
void query(int u){
    if(a[u].l==a[u].r){
        if(a[u].mx) pos=a[u].l;
        return;
    }
    if(a[ls].mx>=a[rs].mx) query(ls);
    else query(rs);
}
int main(){
    n=read(); m=read(); build(1,1,m);
    for(rg int i=1;i<=m;i++){
        int x=read(),y=read()+1,k=read();
        r[i]=(rec){x,k,1}; r[i+m]=(rec){y,k,-1};
    }
    sort(r+1,r+1+(m<<1),cmp);
    int now=0;
    for(rg int i=1;i<=n;i++){
        while(r[++now].pos==i) add(1,r[now].k,r[now].type); now--;
        pos=-1;
        query(1);
        printf("%d\\n",pos);
    }
    return 0;
}

  

#include<cstdio>
#include<algorithm>
#define rg register
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((a[u].l+a[u].r)>>1)
#define N (400010)
using namespace std;
int n,m,tot,pos,del,last[N];
struct opt{
    int pos,del,pre;
}e[N<<1];
struct tree{
    int l,r,mx;
}a[N];
inline int read(){
    int k=0,f=1; char c=getchar();
    while(c<\'0\'||c>\'9\')c==\'-\'&&(f=-1),c=getchar();
    while(\'0\'<=c&&c<=\'9\')k=k*10+c-\'0\',c=getchar();
    return k*f;
}
inline int max(int x,int y){return x>y?x:y;}
inline void add(int x,int y,int z){e[++tot]=(opt){y,z,last[x]}; last[x]=tot;}
void build(int u,int l,int r){
    a[u].l=l; a[u].r=r;
    if(l<r) build(ls,l,mid),build(rs,mid+1,r);
}
void update(int u){
    if(a[u].l==a[u].r){a[u].mx+=del; return;}
    update(pos<=mid?ls:rs);
    a[u].mx=max(a[ls].mx,a[rs].mx);
}
void query(int u){
    if(a[u].l==a[u].r){
        if(a[u].mx) pos=a[u].l;
        return;
    }
    query(a[ls].mx>=a[rs].mx?ls:rs);
}
int main(){
    n=read(); m=read(); build(1,1,m);
    for(rg int i=1,l,r,d;i<=m;i++) l=read(),r=read(),add(l,d=read(),1),add(r+1,d,-1);
    for(rg int i=1;i<=n;i++){
        for(rg int j=last[i];j;j=e[j].pre) pos=e[j].pos,del=e[j].del,update(1);
        pos=-1; query(1); printf("%d\\n",pos);
    }
    return 0;
}

  

以上是关于洛谷 省选营题目 过年的主要内容,如果未能解决你的问题,请参考以下文章

洛谷T21778 过年

洛谷.T21778.过年(线段树 扫描线法)

新年伊始——Day 10

洛谷P1198 [JSOI2008]最大数

洛谷P2024 食物链

[洛谷P3261] [JLOI2015]城池攻占(左偏树)