某毒瘤比赛的一题
又是动态开点线段树
每次都写不出来
只能看看题解勉强维持生活
#include <bits/stdc++.h>
#define il inline
#define Max 20000005
#define Mod 998244353
#define int long long
#define ll long long
#define dec(x) (x=(x==0?Mod-1:x-1))
#define inc(x) (x=(x==Mod-1?0:x+1))
#define ct(x) ((1ll*x*(x+1)>>1)%Mod)
#define cg(x) (x=(x%Mod+Mod)%Mod)
#define getchar() (tt==ss&&(tt=(ss=In)+fread(In,1,2333,stdin),ss==tt)?EOF:*ss++)
using namespace std;
char In[2333],*ss=In,*tt=In;
namespace lyzqs
{
il ll read()
{
char c=getchar();
ll x=0,f=1;
while(c>'9'||c<'0')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int pre[Max],suf[Max],rt,ls[Max],rs[Max],cnt=0;
bool ok[Max];
ll m,ans=0;
ll n;
il void mdf(int &x,ll l,ll r,ll ql,ll qr)
{
if(!x) x=++cnt;
if(ql<=l&&r<=qr)
{
ok[x]=1;
return;
}
ll mid=(l+r)>>1;
if(ql<mid) mdf(ls[x],l,mid,ql,qr);
if(qr>mid) mdf(rs[x],mid,r,ql,qr);
}
il void pushup(int x)
{
ans=(ans+1ll*suf[ls[x]]*pre[rs[x]])%Mod;
cg(ans);
if(ok[x]&&!ok[ls[x]]&&!ok[rs[x]]) dec(ans);
if(!ok[x]&&(ok[ls[x]]||ok[rs[x]])) inc(ans);
pre[x]+=pre[ls[x]]+!ok[x]+(!ok[ls[x]])*(pre[rs[x]]-!ok[rs[x]]);
suf[x]+=suf[rs[x]]+!ok[x]+(!ok[rs[x]])*(suf[ls[x]]-!ok[ls[x]]);
cg(pre[x]),cg(suf[x]);
}
il void qry(int &x,ll l,ll r)
{
if(r-l==1)
{
ans+=!ok[x];
suf[x]=pre[x]=!ok[x];
return;
}
if(!x)
{
x=++cnt;
suf[x]=pre[x]=(r-l)%Mod;
ans+=ct(pre[x]);
cg(ans);
return;
}
ll mid=(l+r)>>1;
qry(ls[x],l,mid);
qry(rs[x],mid,r);
pushup(x);
}
void main()
{
n=read();
m=read();
for(int i=1;i<=m;i++)
{
ll l=read(),r=read();
mdf(rt,0,n,l-1,r);
}
qry(rt,0,n);
printf("%lld\n",ans);
}
}
signed main()
{
lyzqs::main();
}
最后一次更新于2021-09-28 02:19:57
0 条评论