暑期集训7
作者:互联网
130 rank 39
T1:T2:暴力模拟T3 T4:【甜圈】线段树(hash区间加乘或者直接维护区间信息)
T4:给你n个盒子,初始为空,支持t个操作,每次(l,r,xi),表示在[l,r]区间编号的盒子有序放上xi编号物品。求最终满足盒子里的物品恰好是k个而且编号从小到大1--k的盒子数量。
[1]赛时自己打了个线段树,WA得很潇洒(10tps)
[2]正解1:线段树的思路,但是非常巧妙而且简单。你想象每次给一段区间操作,就像按照顺序放一堆有编号的东西,我只关注每次相邻的编号是否连续,因此我只在树上每个节点维护
2个信息:完整区间覆盖的最早的物品编号st,最晚的ed。如果不是完整继续下放,就像是对于包含关系的节点形成了由上到下的由st和ed拼接起来的“一条龙”。
(1)可以很好避免对于覆盖问题的判断,因为如果维护lazy标记那最新的lazy会覆盖上一个,但是我下放的时候节点合法性需要用到最早的一个
(2)可以及时排除冗余,当且仅当拼接会产生不合法,及时=-1,update和query根本不进去,复杂度就有了保证(本来就有保证!)
正解2:hash维护序列是否合法,区间加乘。
hash
const int N=2e5+10;
ull jia[N<<2],che[N<<2];
ull fina;
#define lson (rt<<1)
#define rson (rt<<1|1)
const ull base=131;
int n,k,t;
inline void build(int rt,int l,int r)
{
che[rt]=1;if(l==r)return ;
int mid=(l+r)>>1;
build(lson,l,mid);build(rson,mid+1,r);
}
inline void pushdown(int rt)
{
if(che[rt]!=1)//乘的在先
{
che[lson]*=che[rt];
che[rson]*=che[rt];
jia[lson]*=che[rt];
jia[rson]*=che[rt];
che[rt]=1;
}
if(jia[rt])
{
jia[lson]+=jia[rt];
jia[rson]+=jia[rt];
jia[rt]=0;
}
}
inline void update(int rt,int l,int r,int L,int R,int opt)
{
if(L<=l&&r<=R)
{
jia[rt]*=base;che[rt]*=base;jia[rt]+=opt;
return;
}
pushdown(rt);
int mid=(l+r)>>1;
if(L<=mid)update(lson,l,mid,L,R,opt);
if(R>mid)update(rson,mid+1,r,L,R,opt);
}
inline int query(int rt,int l,int r)
{
if(l==r)
{
if(che[rt]+jia[rt]==fina)return 1;
return 0;
}
int mid=(l+r)>>1;
pushdown(rt);
return query(lson,l,mid)+query(rson,mid+1,r);
}
int main()
{
//freopen("d.in","r",stdin);
//freopen("c1.out","w",stdout);
n=re(),k=re(),t=re();fina=1;
_f(i,1,k)fina=fina*base+i;
build(1,1,n);
_f(i,1,t)
{
int lo=re(),ro=re(),xi=re();
update(1,1,n,lo,ro,xi);
}
chu("%d",query(1,1,n));
return 0;
}
const int N=2e5+10;
int n,k,t;
#define lson (rt<<1)
#define rson (rt<<1|1)
int st[N<<2],ed[N<<2];
inline void pushdown(int rt)
{
if(!st[rt])return;
if(!st[lson])st[lson]=st[rt],ed[lson]=ed[rt];
else if(ed[lson]!=st[rt]-1)ed[lson]=st[lson]=-1;
else ed[lson]=ed[rt];
if(!st[rson])st[rson]=st[rt],ed[rson]=ed[rt];
else if(ed[rson]!=st[rt]-1)ed[rson]=st[rson]=-1;
else ed[rson]=ed[rt];
st[rt]=ed[rt]=0;
}
inline void update(int rt,int l,int r,int L,int R,int opt)
{
if(st[rt]==-1)return;
if(L<=l&&r<=R)
{
if(!st[rt]){st[rt]=ed[rt]=opt;}
else if(ed[rt]!=opt-1)st[rt]=ed[rt]=-1;
else ed[rt]=opt;
return;
}
int mid=(l+r)>>1;pushdown(rt);
if(L<=mid)update(lson,l,mid,L,R,opt);
if(R>mid)update(rson,mid+1,r,L,R,opt);
}
inline int query(int rt,int l,int r)
{
if(st[rt]==-1)return 0;
if(l==r)return (st[rt]==1&&ed[rt]==k);
pushdown(rt);int mid=(l+r)>>1;
return query(lson,l,mid)+query(rson,mid+1,r);
}
int main()
{
//freopen("d.in","r",stdin);
//freopen("c1.out","w",stdout);
n=re(),k=re(),t=re();
_f(i,1,t)
{
int lk=re(),rk=re(),xi=re();
update(1,1,n,lk,rk,xi);
}
chu("%d",query(1,1,n));
return 0;
}
标签:rt,jia,int,mid,暑期,re,query,集训 来源: https://www.cnblogs.com/403caorong/p/16610205.html