ABC255Ex 线段树代码求调
  • 板块学术版
  • 楼主FelFa_1414666
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/6/13 15:29
  • 上次更新2023/10/27 23:22:47
查看原帖
ABC255Ex 线段树代码求调
209168
FelFa_1414666楼主2022/6/13 15:29

非递归线段树代码。大致思路就是将数轴离散化,每次整个区间加,再查询区间,区间赋值。add标记是加,era标记是是否清空,val是该区间一天长出果实的量。

写完交上去直接 WA 了 24 个点,但是和榜一代码对拍了将近一天没有拍出来,大数据小数据都试过了。有这么离谱么...

代码如下,求大佬们帮调orz

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define F first
#define S second
using namespace std;
const ll MOD=998244353;
const ll inv2=499122177;
int q,segh;
ll n,d[200005],L[200005],R[200005],val[800005],sum[800005],add[400005];
bool era[400005];
ll getsum(ll l,ll r){
    l%=MOD,r%=MOD;
    return (l+r)%MOD*((r-l+1+MOD)%MOD)%MOD*inv2%MOD;
}
void Apply(int p,ll x)
{
    if (x==-1)
    {
        sum[p]=add[p]=0ll;
        if (p<n)
            era[p]=1;
    }
    else
    {
        x%=MOD;
        sum[p]=(sum[p]+x*val[p]%MOD)%MOD;
        if (p<n)
            add[p]=(add[p]+x)%MOD;
    }
}
void calc(int p)
{
    if (era[p])
        sum[p]=0ll;
    else
        sum[p]=(sum[p<<1]+sum[p<<1|1]+add[p]*val[p]%MOD)%MOD;
}
void build(int l,int r)
{
    for(l+=n,r+=n-1;l>1;)
    {
        l>>=1,r>>=1; 
        for(int i=r;i>=l;i--)
            calc(i);
    }
}
void push(int l,int r)
{
    l+=n,r+=n-1;
    for(int h=segh;h;h--)
        for(int i=l>>h;i<=r>>h;i++)
        {
            if (era[i])
            {
                Apply(i<<1,-1);
                Apply(i<<1|1,-1);
                era[i]=0;
            }
            if (add[i])
            {
                Apply(i<<1,add[i]);
                Apply(i<<1|1,add[i]);
                add[i]=0ll;
            }
        }
}
void modify(int l,int r,ll x)
{
    int l0=l,r0=r;
    push(l,l+1),push(r-1,r);
    for(l+=n,r+=n;l<r;l>>=1,r>>=1)
    {
        if (l&1) Apply(l++,x);
        if (r&1) Apply(--r,x);
    }
    build(l0,l0+1),build(r0-1,r0);
}
ll query(int l,int r)
{
    ll res=0ll;
    push(l,l+1),push(r-1,r);
    for(l+=n,r+=n;l<r;l>>=1,r>>=1)
    {
        if (l&1) res=(res+sum[l++])%MOD;
        if (r&1) res=(res+sum[--r])%MOD;
    }
    return res;
}
int main()
{
    ios::sync_with_stdio(false),cin.tie(nullptr);
    cin>>n>>q;
    vector<ll> b;
    for(int i=1;i<=q;i++)
    {
        cin>>d[i]>>L[i]>>R[i];
        b.pb(L[i]),b.pb(R[i]+1);
    }
    sort(b.begin(),b.end());
    b.erase(unique(b.begin(),b.end()),b.end());
    n=b.size();
    segh=(int)(sizeof(ll)*8-__builtin_clzll(n));
    b.pb(b.back()+1);
    for(int i=0;i<n-1;i++)
        val[i+n]=getsum(b[i],b[i+1]-1);
    for(int i=n-1;i;i--)
        val[i]=(val[i<<1]+val[i<<1|1])%MOD;
    for(int i=1;i<=q;i++)
    {
        L[i]=lower_bound(b.begin(),b.end(),L[i])-b.begin();
        R[i]=lower_bound(b.begin(),b.end(),R[i]+1)-b.begin();
        modify(0,n,d[i]-d[i-1]);
        cout<<query(L[i],R[i])<<endl;
        modify(L[i],R[i],-1);
    }
    return 0;
}
2022/6/13 15:29
加载中...