题解 P8527【[Ynoi2003] 樋口円香】

Link

题意

给出长为 n 的序列 a,bb 序列初始为 0m 次操作,每次给出 a 中的一个区间 [l,r]L,执行 i[l,r],bi+Llbi+Ll+ai

求出所有操作后的 b 序列。

n105m106

思路

乐子一血。

对序列 a 按照块长为 B 分块,对于一次操作,若 l,r 同块,则直接加,否则先对散块暴力,整块存下来暂不处理。

所有询问的散块处理完之后,处理整块。对于每个块 [bL,bR],我们记录 ci 表示这个块加到 b 序列中以 i 开始的等长区间的次数,di=abL+i(ibRbL)。令这个块对 bi 的贡献为 resi,则有 resi=j=1icjdij,可以卷积。

复杂度为 O(mB+(nlogn+m)nB),取 B=O(\sqrt\dfrac{n^2\log n+nm}m) 得到最优复杂度 O(nmlogn+mn)

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
namespace IO{//by cyffff

}
const int N=131072,mod=998244353;
namespace Init{
    int fac[N],ifac[N],inv[N],G[17][N];
    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;
    }
    inline void getG(){
        for(int i=0;i<17;i++){
            int *P=G[i],W=1<<i;
            P[0]=1;
            P[1]=qpow(3,(mod-1)/(1<<i+1));
            const int tmp=P[1];
            for(int j=2;j<W;j++)
                P[j]=1ll*P[j-1]*tmp%mod;
        }
    }
    inline void Prefix(int L){
        fac[0]=1;
        for(int i=1;i<=L;i++)
            fac[i]=1ll*fac[i-1]*i%mod;
        ifac[L]=qpow(fac[L],mod-2);
        for(int i=L;i>=1;i--)
            ifac[i-1]=1ll*ifac[i]*i%mod;
        for(int i=1;i<=L;i++)
            inv[i]=1ll*fac[i]*ifac[i-1]%mod;
    }
}
using namespace Init;
namespace Poly{
    int lim,rev[N];
    int F[N],G[N],H[N];
    inline void init(int n,int mode=1){
        if(mode){
            int l=0;
            for(lim=1;lim<=n;lim<<=1)l++;
            for(int i=1;i<lim;i++)
                rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
        }else{
            for(lim=1;lim<=n;lim<<=1);
        }
    }
    inline void NTT(int *a,int T){
        for(int i=0;i<lim;i++)
            if(i<rev[i])
                swap(a[i],a[rev[i]]);
        for(int i=1,o=0;i<lim;i<<=1,o++){
            const int *P=::G[o];
            for(int j=0;j<lim;j+=(i<<1)){
                int t1,t2;
                for(int k=0;k<i;k++){
                    t1=a[j+k];
                    t2=1ll*P[k]*a[i+j+k]%mod;
                    a[j+k]=(t1+t2)%mod;
                    a[i+j+k]=(t1-t2+mod)%mod;
                }
            }
        }
        if(T==1) return ;
        int Inv=qpow(lim,mod-2);
        reverse(a+1,a+lim);
        for(int i=0;i<lim;i++)
            a[i]=1ll*a[i]*Inv%mod;
    }
    inline void Mul(int *a,int *b){
        for(int i=0;i<lim;i++)
            F[i]=b[i];
        NTT(a,1),NTT(F,1);
        for(int i=0;i<lim;i++)
            a[i]=1ll*a[i]*F[i]%mod;
        NTT(a,-1);
    }
}
const int T=1e5+10,Q=1e6+10,sq=sqrt(1.0*T*T*log2(T)/Q+Q)*2;
int n,q,blk,a[T],b[T],c[N],d[N],bel[T],bl[T],br[T];
struct Query{
    int l,bL,bR,L;
}que[Q];
inline void solve(int bL,int bR){
    int D=bel[bL],len=bR-bL+1;
    for(int i=0;i<=Poly::lim;i++)
        c[i]=d[i]=0;
    for(int i=1;i<=q;i++)
        if(que[i].bL<=D&&D<=que[i].bR)
            c[que[i].L+bL-que[i].l]++;
    for(int i=1;i<=len;i++)
        d[i-1]=a[bL+i-1];
    Poly::Mul(c,d);
    for(int i=1;i<=n;i++)
        b[i]+=c[i];
}
int main(){
    n=read();
    getG(),Poly::init(n+2000);
    for(int i=1;i<=n;i++)
        a[i]=read();
    for(int i=1;i<=n;i+=sq){
        blk++;
        bl[blk]=i,br[blk]=min(i+sq-1,n);
        for(int j=bl[blk];j<=br[blk];j++)
            bel[j]=blk;
    }
    q=read();
    for(int i=1;i<=q;i++){
        int l=read(),r=read(),L=read();
        int bL=bel[l],bR=bel[r];
        if(bL==bR){
            for(int j=l;j<=r;j++)
                b[L+j-l]+=a[j];
        }else{
            for(int j=l;j<=br[bL];j++)
                b[L+j-l]+=a[j];
            for(int j=bl[bR];j<=r;j++)
                b[L+j-l]+=a[j];
            que[i]={l,bL+1,bR-1,L};
        }
    }
    for(int i=1;i<=blk;i++)
        solve(bl[i],br[i]);
    for(int i=1;i<=n;i++)
        write(b[i]),putc('\n');
    flush();
}

再见 qwq~

posted @   ffffyc  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示