1 条题解
-
0
自动搬运
来自洛谷,原作者为

mrsrz
故障机器人搬运于
2025-08-24 22:07:16,当前版本为作者最后更新于2018-12-23 10:03:31,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
这线段树的写法不怎么优美啊QAQ以下讨论都是按照题目上的左开右闭线段树来的。
线段树上分治。
首先按照题意模拟,把该删的节点都打上删除标记。动态开点,时间复杂度。
然后在线段树上分治。
令表示节点表示的区间中,有多少个使得区间满足条件。
表示节点表示的区间中,有多少个使得区间满足条件。
分别表示节点的左、右儿子。
按顺序访问每个节点,先考虑如下特殊情况。
- 若该节点是叶子,且没被删除,则,答案加1。
- 若该节点是叶子,且被删除了,则,答案减1。
- 若该节点没被开辟,则节点内的区间任选,答案加,。
对于一般情况,该区间内的贡献就是。
还有一些特殊情况:
- 若被删除且均未被删除,则统计答案的时候,被统计进去了,实际应该不符合条件,因此答案要减1。
- 若没被删除且中有节点被删除,则统计答案的时候,没被统计,实际是符合条件的,因此答案要加1。
接下来计算节点的和,这里只考虑。
的个区间一定是可行的。
的个区间可行,必须满足没被删除(因为要补上区间)。
若和均未被删除,则区间被计算进去了,先减去这个区间的1。
再单独考虑是否被删除,看是否要加上区间即可。
于是就有了代码注释中的那个转移。
则反过来同样方法考虑即可。
这部分的时间复杂度也是的,所以总时间复杂度。
线段树空间开大点即可。
Code:
#include<cstdio> #include<cstring> #include<algorithm> using std::min;using std::max; typedef long long LL; const int md=998244353,N=201*100000; int ls[N],rs[N],rt; bool del[N]; LL n;int pre[N],suf[N];int m,node=0,ans=0; //pre每个节点前缀可行区间个数,suf后缀 void split(int&o,LL l,LL r,const LL&L,const LL&R){ if(!o)o=++node; if(L==l&&r==R)del[o]=1;else{ const LL mid=l+r>>1; if(L<mid)split(ls[o],l,mid,L,min(R,mid)); if(mid<R)split(rs[o],mid,r,max(L,mid),R); } } inline int CC(LL x){return(x*(x+1)>>1)%md;} inline void upd(int&x){x+=x>>31&md;} void query(int&o,LL l,LL r){ if(l+1==r){//底层 ans+=(suf[o]=pre[o]=!del[o]); if(ans>=md)ans-=md; return; } if(!o){//没被访问 o=++node; pre[o]=suf[o]=(r-l)%md; upd(ans+=CC((r-l)%md)-md); return; } const LL mid=l+r>>1; query(ls[o],l,mid); query(rs[o],mid,r); upd(ans+=1LL*suf[ls[o]]*pre[rs[o]]%md-md); if(del[o]&&!del[ls[o]]&&!del[rs[o]])upd(--ans);//自己被删除,两个儿子没被删除 if(!del[o]&&(del[ls[o]]||del[rs[o]]))upd(ans=ans+1-md);//自己没被删除,两个儿子至少一个被删除 upd(pre[o]=(pre[ls[o]]+!del[o]+(!del[ls[o]])*(pre[rs[o]]-!del[rs[o]]))-md);//前缀=左边的前缀+[整个节点是否可行]+[左边整个节点是否可行]*(右边的前缀-[右边整个节点是否可行]) upd(suf[o]=(suf[rs[o]]+!del[o]+(!del[rs[o]])*(suf[ls[o]]-!del[ls[o]]))-md);//同理 } int main(){ scanf("%lld%d",&n,&m); while(m--){ LL l,r; scanf("%lld%lld",&l,&r); split(rt,0,n,l-1,r); } query(rt,0,n); printf("%d\n",ans); return 0; }
- 1
信息
- ID
- 4057
- 时间
- 2000ms
- 内存
- 500MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者