题解 NOIP2022 62C【区间】
题意
给出 个数轴上的区间 ,定义 , 个询问 ,求出 ,对 取模。
,,,时限 4s。
思路
数轴上的区间不好处理,将 用 表示,每个点 对应了 到 的区间。
考虑离线扫描线。这个区间应该是离不开颜色段均摊的。
我们定义 为扫到 时刻的颜色段均摊,每一个颜色段用 表示,其中 为此段属于哪个区间 , 表示这段的长度。
考虑要求什么:
在插入、删除颜色段的时候在 的位置修改一下。发现一个 ,它会对每个时刻都有 的贡献。考虑使用维护区间历史版本和的线段树,一颗维护 ,一颗维护 。
历史版本和线段树用加一次函数的形式更容易理解和维护。
预处理 的逆元,时间复杂度 。
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
namespace IO{//by cyffff
}
#define sit set<node>::iterator
const int N=8e5+10,Q=2e6+10,mod=998244353;
inline int qpow(int x,int y){
int res=1;
while(y){
if(y&1) res=1ll*res*x%mod;
x=1ll*x*x%mod;
y>>=1;
}
return res;
}
int n,q,L[N],R[N],ans[Q],inv[N];
struct Query{
int l,id;
};
vector<Query>vec[N];
struct node{
int l;
mutable int r,v;
node(int L=0,int R=0,int V=0){l=L,r=R,v=V;}
inline friend bool operator<(const node &a,const node &b){
return a.l<b.l;
}
};
struct Line{
int k,b;
Line(int K=0,int B=0){ k=K%mod,b=B%mod; }
inline friend Line operator+(const Line &a,const Line &b){
return {(a.k+b.k)%mod,(a.b+b.b)%mod};
}
inline int getv(int x){
return (1ll*k*x+b)%mod;
}
};
struct Segment_Tree{
#define ls (rt<<1)
#define rs (rt<<1|1)
Line sum[N<<2];
inline void pushup(int rt){
sum[rt]=sum[ls]+sum[rs];
}
inline void modify(int rt,int l,int r,int p,Line v){
if(l==r){
sum[rt]=sum[rt]+v;
return ;
}
int mid=l+r>>1;
if(p<=mid) modify(ls,l,mid,p,v);
else modify(rs,mid+1,r,p,v);
pushup(rt);
}
inline int query(int rt,int l,int r,int L,int R,int x){
if(L<=l&&r<=R)
return sum[rt].getv(x);
int mid=l+r>>1,ans=0;
if(L<=mid) ans=(ans+query(ls,l,mid,L,R,x))%mod;
if(R>mid) ans=(ans+query(rs,mid+1,r,L,R,x))%mod;
return ans;
}
}T1,T2;
set<node>st;
inline sit split(int p){
sit it=st.lower_bound(node(p));
if(it!=st.end()&&it->l==p)
return it;
--it;
int r=it->r,v=it->v;
it->r=p-1;
return st.insert(node(p,r,v)).first;
}
inline void ins(int l,int r,int id){
if(l>r) return ;
sit itr=split(r+1),itl=split(l);
for(sit it=itl;it!=itr;++it){
int x=it->v,y=it->r-it->l+1;
T1.modify(1,0,n,x,Line(mod-1ll*x*y%mod,1ll*x*y%mod*(id-1)%mod));
T2.modify(1,0,n,x,Line(mod-y,1ll*y*(id-1)%mod));
}
int x=id,y=r-l+1;
T1.modify(1,0,n,x,Line(1ll*x*y%mod,mod-1ll*x*y%mod*(id-1)%mod));
T2.modify(1,0,n,x,Line(y,mod-1ll*y*(id-1)%mod));
st.erase(itl,itr),st.insert(node(l,r,id));
}
/*
2 1
1 5
4 8
1 2
*/
int main(){
n=read(),q=read();
for(int i=1;i<=n;i++)
L[i]=read(),R[i]=read()-1;
st.insert(node(1,mod));
for(int i=1;i<=q;i++){
int l=read(),r=read();
vec[r].push_back((Query){l,i});
}
for(int i=1;i<=n;i++){
ins(L[i],R[i],i);
for(auto q:vec[i])
ans[q.id]=(T1.query(1,0,n,q.l,n,i)-1ll*(q.l-1)*T2.query(1,0,n,q.l,n,i)%mod+mod)%mod*qpow(1ll*(i-q.l+1)*(i-q.l+2)/2%mod,mod-2)%mod;
}
for(int i=1;i<=q;i++)
write(ans[i]),putc('\n');
flush();
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2021-11-22 题解 CF913F【Strongly Connected Tournament】