Gym 100541 E ACM (线段树板子)

##2014 ACM-ICPC Vietnam National Second Round E

经典线段树lazytag+素数拆分

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <iostream>

#define lint long long
using namespace std;


const lint sushu[40]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,
67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149};

struct node
{
    lint shu[35];
    lint all[35];

}tree[300000];

node temp;

lint pow_mod(lint a, lint n, lint m)
{
    lint ans = 1;
    while(n)
    {
        if(n&1)
        {
            ans = (ans * a) % m;
        }
        a = (a * a) % m;
        n >>= 1;
    }
    return ans;
}


int jia(lint l,lint r,lint ll,lint rr,lint now)
{

    if(ll<=l&&rr>=r)
    {
        for(lint j=0;j<35;j++)
        {
            tree[now].shu[j]+=temp.shu[j];
            tree[now].all[j]+=temp.shu[j]*(r-l+1);
        }

        return 0;
    }

    lint mid=(l+r)/2;

    for(lint j=0;j<35;j++)
    {
        tree[now*2].shu[j]+=tree[now].shu[j];
        tree[now*2+1].shu[j]+=tree[now].shu[j];

        tree[now*2].all[j]+=(mid-l+1)*tree[now].shu[j];
        tree[now*2+1].all[j]+=(r-mid)*tree[now].shu[j];

        tree[now].shu[j]=0;
    }

    if(rr<=mid)
        jia(l,mid,ll,rr,now*2);
    else if(ll>=mid+1)
        jia(mid+1,r,ll,rr,now*2+1);
    else
    {
        jia(l,mid,ll,mid,now*2);
        jia(mid+1,r,mid+1,rr,now*2+1);
    }

    for(lint j=0;j<35;j++)
    {
        tree[now].all[j]=tree[now*2].all[j]+tree[now*2+1].all[j];
    }

    return 0;
}

node check(lint l,lint r,lint ll,lint rr,lint now)
{

    if(ll<=l&&rr>=r)
    {
        return tree[now];
    }

    lint mid=(l+r)/2;

    for(lint j=0;j<35;j++)
    {
        tree[now*2].shu[j]+=tree[now].shu[j];
        tree[now*2+1].shu[j]+=tree[now].shu[j];

        tree[now*2].all[j]+=(mid-l+1)*tree[now].shu[j];
        tree[now*2+1].all[j]+=(r-mid)*tree[now].shu[j];

        tree[now].shu[j]=0;
    }


    if(rr<=mid)
        return check(l,mid,ll,rr,now*2);
    else if(ll>=mid+1)
        return check(mid+1,r,ll,rr,now*2+1);
    else
    {
        node a=check(l,mid,ll,mid,now*2);
        node b=check(mid+1,r,mid+1,rr,now*2+1);

        for(lint j=0;j<35;j++)
        a.all[j]+=b.all[j];
        return a;
    }

}


int main()
{
    lint n,m,t,k,ans,the,a,b,c;


    scanf("%lld",&t);
    {
        while(t--)
        {
            scanf("%lld",&n);scanf("%lld",&m);
            memset(tree,0,sizeof tree);


            for(lint i=0;i<m;i++)
            {
                scanf("%lld",&k);

                if(k==0)
                {
                    scanf("%lld%lld%lld",&a,&b,&c);

                    if(a<=b)
                    {
                        node x=check(1,n,a,b,1);
                        ans=1;

                        for(lint j=0;j<35;j++)
                        {
                            if(x.all[j]>0)
                            {
                                ans*=1LL*pow_mod(sushu[j],x.all[j],c);
                                ans%=c;
                            }
                        }
                        ans%=c;
                        printf("%lld\n",(ans%c));
                    }
                    else
                    {
                        node x=check(1,n,a,n,1);
                        node y=check(1,n,1,b,1);

                        ans=1;

                        for(lint j=0;j<35;j++)
                        {
                            if(x.all[j]>0)
                            {
                                ans*=1LL*pow_mod(sushu[j],x.all[j],c);
                                ans%=c;
                            }
                            if(y.all[j]>0)
                            {
                                ans*=1LL*pow_mod(sushu[j],y.all[j],c);
                                ans%=c;
                            }
                        }
                        ans%=c;
                        cout<<ans<<endl;
                    }

                }
                else if(k==1)
                {
                    scanf("%lld%lld%lld",&a,&b,&c);

                    for(lint j=0;j<35;j++)
                    {
                        temp.shu[j]=0;
                        while(c%sushu[j]==0)
                        {
                            temp.shu[j]++;
                            c/=sushu[j];
                        }
                    }

                    if(a<=b)
                    jia(1,n,a,b,1);
                    else jia(1,n,a,n,1),jia(1,n,1,b,1);
                }
                else if(k==2)
                {
                    scanf("%lld%lld%lld",&a,&b,&c);

                    for(lint j=0;j<35;j++)
                    {
                        temp.shu[j]=0;
                        while(c%sushu[j]==0)
                        {
                            temp.shu[j]--;
                            c/=sushu[j];
                        }
                    }

                    if(a<=b)
                    jia(1,n,a,b,1);
                    else jia(1,n,a,n,1),jia(1,n,1,b,1);
                }
            }

        }


    }


    return 0;
}

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <iostream>

#define lint long long
using namespace std;


const lint sushu[40]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,
67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149};

struct node
{
    lint shu[35];
    lint all[35];

}tree[300000];

node temp;

lint pow_mod(lint a, lint n, lint m)
{
    lint ans = 1;
    while(n)
    {
        if(n&1)
        {
            ans = (ans * a) % m;
        }
        a = (a * a) % m;
        n >>= 1;
    }
    return ans;
}


int jia(lint l,lint r,lint ll,lint rr,lint now)
{

    if(ll<=l&&rr>=r)
    {
        for(lint j=0;j<35;j++)
        tree[now].shu[j]+=temp.shu[j];

        if(l==r)
        {
            for(lint j=0;j<35;j++)
            {
                tree[now].all[j]+=tree[now].shu[j];
                tree[now].shu[j]=0;
            }
        }

        return 0;
    }

    for(lint j=0;j<35;j++)
    tree[now].all[j]+=temp.shu[j]*(rr-ll+1);

    for(lint j=0;j<35;j++)
    {
        tree[now*2].shu[j]+=tree[now].shu[j];
        tree[now*2+1].shu[j]+=tree[now].shu[j];

        tree[now].all[j]+=(r-l+1)*tree[now].shu[j];
        tree[now].shu[j]=0;
    }

    lint mid=(l+r)/2;
    if(rr<=mid)
        jia(l,mid,ll,rr,now*2);
    else if(ll>=mid+1)
        jia(mid+1,r,ll,rr,now*2+1);
    else
    {
        jia(l,mid,ll,mid,now*2);
        jia(mid+1,r,mid+1,rr,now*2+1);
    }

    return 0;
}

node check(lint l,lint r,lint ll,lint rr,lint now)
{

    if(ll<=l&&rr>=r)
    {
        if(l==r)
        for(lint j=0;j<35;j++)
        {
            tree[now].all[j]+=(r-l+1)*tree[now].shu[j];
            tree[now].shu[j]=0;
        }
        else
        for(lint j=0;j<35;j++)
        {
            tree[now*2].shu[j]+=tree[now].shu[j];
            tree[now*2+1].shu[j]+=tree[now].shu[j];

            tree[now].all[j]+=(r-l+1)*tree[now].shu[j];
            tree[now].shu[j]=0;
        }

        return tree[now];
    }

    for(lint j=0;j<35;j++)
    {
        tree[now*2].shu[j]+=tree[now].shu[j];
        tree[now*2+1].shu[j]+=tree[now].shu[j];

        tree[now].all[j]+=(r-l+1)*tree[now].shu[j];
        tree[now].shu[j]=0;
    }


    lint mid=(l+r)/2;
    if(rr<=mid)
        return check(l,mid,ll,rr,now*2);
    else if(ll>=mid+1)
        return check(mid+1,r,ll,rr,now*2+1);
    else
    {
        node a=check(l,mid,ll,mid,now*2);
        node b=check(mid+1,r,mid+1,rr,now*2+1);

        for(lint j=0;j<35;j++)
        a.all[j]+=b.all[j];
        return a;
    }

}


int main()
{
    lint n,m,t,k,ans,the,a,b,c;


    scanf("%lld",&t);
    {
        while(t--)
        {
            scanf("%lld",&n);scanf("%lld",&m);
            memset(tree,0,sizeof tree);


            for(lint i=0;i<m;i++)
            {
                scanf("%lld",&k);

                if(k==0)
                {
                    scanf("%lld%lld%lld",&a,&b,&c);

                    if(a<=b)
                    {
                        node x=check(1,n,a,b,1);
                        ans=1;

                        for(lint j=0;j<35;j++)
                        {
                            if(x.all[j]>0)
                            {
                                ans*=1LL*pow_mod(sushu[j],x.all[j],c);
                                ans%=c;
                            }
                        }
                        ans%=c;
                        printf("%lld\n",(ans%c));
                    }
                    else
                    {
                        node x=check(1,n,a,n,1);
                        node y=check(1,n,1,b,1);

                        ans=1;

                        for(lint j=0;j<35;j++)
                        {
                            if(x.all[j]>0)
                            {
                                ans*=1LL*pow_mod(sushu[j],x.all[j],c);
                                ans%=c;
                            }
                            if(y.all[j]>0)
                            {
                                ans*=1LL*pow_mod(sushu[j],y.all[j],c);
                                ans%=c;
                            }
                        }
                        ans%=c;
                        cout<<ans<<endl;
                    }

                }
                else if(k==1)
                {
                    scanf("%lld%lld%lld",&a,&b,&c);

                    for(lint j=0;j<35;j++)
                    {
                        temp.shu[j]=0;
                        while(c%sushu[j]==0)
                        {
                            temp.shu[j]++;
                            c/=sushu[j];
                        }
                    }

                    if(a<=b)
                    jia(1,n,a,b,1);
                    else jia(1,n,a,n,1),jia(1,n,1,b,1);
                }
                else if(k==2)
                {
                    scanf("%lld%lld%lld",&a,&b,&c);

                    for(lint j=0;j<35;j++)
                    {
                        temp.shu[j]=0;
                        while(c%sushu[j]==0)
                        {
                            temp.shu[j]--;
                            c/=sushu[j];
                        }
                    }

                    if(a<=b)
                    jia(1,n,a,b,1);
                    else jia(1,n,a,n,1),jia(1,n,1,b,1);
                }
            }

        }


    }


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值