
【题解】
差分+扫描线+权值线段树。
我们先把区间操作差分,变成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
",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
",pos);
}
return 0;
}