「杂题乱刷2」CF311D

题目链接

CF311D Interval Cubing

解题思路

实际上不难。

注意到特殊的模数,考虑是否会出现循环节。

然后打表发现循环节长度为 \(48\)

那么我们显然使用分快维护块内乘了几次即可,因为有 \(48\) 的极小循环节。

块长取 \(50\) 显然是优秀的。

参考代码

ll n,q;
ll a[100010][50];
ll sq;
ll L[100010],R[100010];
ll b[100010];
ll now[100010];
ll S[100010][50];
ll f(ll x)
{
    x%=mod;
    return x*x%mod*x%mod;
}
ll opt,l,r;
void _clear(){}
void solve()
{
    _clear();
    cin>>n;
    forl(i,1,n)
    {
        cin>>a[i][0];
        a[i][0]%=mod;
        forl(j,1,47)
            a[i][j]=f(a[i][j-1]);
    }
    sq=50;
    forl(i,1,n)
    {
        L[i]=R[i-1]+1,
        R[i]=min(n,sq*i);
        now[i]=0;
        forl(j,L[i],R[i])
        {
            b[j]=i;
            forl(k,0,47)
                S[i][k]=(S[i][k]+a[j][k])%mod;
                // cout<<a[j][k]<<'?';
        }
    //    cout<<S[i][0]<<' ';
        if(R[i]==n)
            break;
    }
    cout<<endl;
    // forl(i,1,n)
    //     cout<<b[i]<<' ';
    // cout<<endl;
    cin>>q;
    forl(_,1,q)
    {
        cin>>opt>>l>>r;
        if(opt==2)
        {
            if(b[l]==b[r])
            {
                forl(i,l,r)
                {
                    a[i][0]=f(a[i][0]);
                    forl(j,1,47)
                        a[i][j]=f(a[i][j-1]);
                }
                forl(j,0,47)
                    S[b[l]][j]=0;
                forl(j,L[b[l]],R[b[l]])
                    forl(k,0,47)
                        S[b[l]][k]=(S[b[l]][k]+a[j][k])%mod;
                continue;
            }
            forl(i,l,R[b[l]])
            {
                a[i][0]=f(a[i][0]);
                forl(j,1,47)
                    a[i][j]=f(a[i][j-1]);
            }

            forl(j,0,47)
                S[b[l]][j]=0;
            forl(j,L[b[l]],R[b[l]])
                forl(k,0,47)
                    S[b[l]][k]=(S[b[l]][k]+a[j][k])%mod;
                    
            forl(i,L[b[r]],r)
            {
                a[i][0]=f(a[i][0]);
                forl(j,1,47)
                    a[i][j]=f(a[i][j-1]);
            }
            forl(j,0,47)
                S[b[r]][j]=0;
            forl(j,L[b[r]],R[b[r]])
                forl(k,0,47)
                    S[b[r]][k]=(S[b[r]][k]+a[j][k])%mod;

            forl(i,b[l]+1,b[r]-1)
                now[i]=(now[i]+1)%48;
        }
        else
        {
            if(b[l]==b[r])
            {
                ll sum=0;
                forl(i,l,r)
                    sum=(sum+a[i][now[b[l]]])%mod;
                cout<<sum<<endl;
                continue;
            }
            ll sum=0;
            forl(i,l,R[b[l]])
                sum=(sum+a[i][now[b[l]]])%mod;
                // cout<<a[i][now[b[l]]]<<'>';
            forl(i,L[b[r]],r)
                sum=(sum+a[i][now[b[r]]])%mod;
                // cout<<a[i][now[b[r]]]<<'?';
            forl(i,b[l]+1,b[r]-1)
                sum=(sum+S[i][now[i]])%mod;
                // cout<<S[i][now[i]]<<'&';
            cout<<sum<<endl;
        }
    }
}
posted @ 2025-04-09 15:19  wangmarui  阅读(14)  评论(0)    收藏  举报