• E、小花梨的数组(线段树)


    经典的线段树区间更新题目

    对于每次更新 分为除法标记和乘法标记

    如果乘法标记不为0

    那么我进行除法标记是将乘法标记减一即可

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const long long mod=1000000007;
    
    vector<long long> factor[100015];
    long long a[100005];
    long long cnt=0;
    long long prime[2015];
    long long vis[2010];
    struct node
    {
        long long l;
        long long r;
        long long tag1;
        long long tag2;
    } tree[401010];
    
    long long divi,mul;
    
    long long quick_pow(long long a,long long b)
    {
        long long x;
        x=1;
        a=a%mod;
        while(b)
        {
            if(b%2==1) x=(x*a)%mod;
            b/=2;
            a=(a*a)%mod;
        }
        return x;
    }
    long long ans=1;
    
    void push_down(long long root)
    {
        if(tree[root].l!=tree[root].r)
        {
            if(tree[root*2].tag1>=tree[root].tag2) tree[root*2].tag1-=tree[root].tag2;
            else
            {
                tree[root*2].tag2+=(tree[root].tag2-tree[root*2].tag1),tree[root*2].tag1=0;
            }
            if(tree[root*2+1].tag1>=tree[root].tag2) tree[root*2+1].tag1-=tree[root].tag2;
            else
            {
                tree[root*2+1].tag2+=(tree[root].tag2-tree[root*2+1].tag1),tree[root*2+1].tag1=0;
            }
            tree[root*2].tag1+=tree[root].tag1;
            tree[root*2+1].tag1+=tree[root].tag1;
            tree[root].tag1=0;
            tree[root].tag2=0;
        }
    }
    
    
    
    
    void init(int n)
    {
        for(int i = 2; i <= n; i++)if(!vis[i])
            {
                prime[++cnt] = i;
                for(ll j = (ll)i * i; j <= n; j += i)vis[j] = 1;
            }
    }
    
    void build(long long l,long long r,long long root)
    {
        tree[root].l=l;
        tree[root].r=r;
        tree[root].tag1=0;
        tree[root].tag2=0;
        if(l==r) return ;
        long long mid=(l+r)/2;
        build(l,mid,root*2);
        build(mid+1,r,root*2+1);
    }
    
    void qurey(long long k,long long root)
    {
        if(tree[root].l==tree[root].r&&tree[root].l==k)
        {
            divi=tree[root].tag2;
            mul=tree[root].tag1;
            return ;
        }
        if(tree[root].tag1||tree[root].tag2) push_down(root);
        long long mid=(tree[root].l+tree[root].r)/2;
        if(k<=mid)  qurey(k,root*2);
        else   qurey(k,root*2+1);
    }
    
    void update(long long l,long long  r,long long root,long long op)//l r ¡ä¨²¡À¨ª ?¨´¨°a¡¤??¨º¦Ì?????
    {
    
        if(tree[root].l==l&&tree[root].r==r)//¨¨?1?¡ã¨¹o??¨²?????¨²2?
        {
            if(op==1)
            {
                tree[root].tag1++;
            }
            else
            {
                if(tree[root].tag1>0) tree[root].tag1--;
                else tree[root].tag2++;
            }
            return ;
        }
        if(tree[root].tag1||tree[root].tag2) push_down(root);
        long long mid=(tree[root].l+tree[root].r)/2;
        if(l>mid) update(l,r,root*2+1,op);
        else if(r<=mid) update(l,r,root*2,op);
        else {
            update(l,mid,root<<1,op);
            update(mid+1,r,root<<1|1,op);
        }
    }
    
    int main()
    {
        memset(vis,0,sizeof(vis));
        init(1000);
        long long n,m;
        scanf("%lld%lld",&n,&m);
        for(long long i=1; i<=n; i++)
        {
            scanf("%lld",&a[i]);
            long long tmp=a[i];
            for(long long j=1; prime[j]*prime[j]<=tmp&&j<=cnt; j++)
            {
                while(tmp%prime[j]==0)
                {
                    factor[i].push_back(prime[j]);
                    tmp/=prime[j];
                }
            }
            if(tmp!=1) factor[i].push_back(tmp);
        }
        build(1,n,1);
        while(m--)
        {
            long long op;
            scanf("%lld",&op);
            if(op==1||op==2)
            {
                long long tmp1,tmp2;
                scanf("%lld%lld",&tmp1,&tmp2);
                update(tmp1,tmp2,1,op);
            }
            else
            {
                long long cao;
                scanf("%lld",&cao);
                qurey(cao,1);
                ans=1;
                if(divi>=factor[cao].size())
                {
                    printf("1
    ");
                }
                else
                {
                    for(long long i=divi; i<factor[cao].size(); i++)
                    {
                        ans=(ans*factor[cao][i]);
                    }
                    ans=ans*quick_pow(factor[cao][divi],mul)%mod;
                    printf("%lld
    ",ans);
                }
            }
        }
    }
    
  • 相关阅读:
    数据可视化
    tkinter学习04
    小练习-----银行提款机系统
    python___docx模块
    Django【进阶篇 】
    Django之Cookie/session/防止XSS攻击
    tkinter学习03
    tkinter学习02
    AJAX
    tkinter学习01
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852256.html
Copyright © 2020-2023  润新知