"美登杯" E、小花梨的数组* 线段树

操作过程中标记传递  询问的时候再计算

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define lson l,m,pos<<1
#define rson m+1,r,pos<<1|1
const int N=100000+5;
const int mod=1e9+7;
int f[N*10],prime[N*10],pre[N*10],cnt;

void init()
{
    f[1]=1;
    prime[0]=prime[1]=1;
    rep(i,2,1e6)
    {
        if(prime[i]==0)
        {
            pre[++cnt]=i;
            f[i]=i;
        }
        for(int j=1;j<=cnt&&pre[j]*i<=1e6;j++)
        {
            prime[i*pre[j]]=1;
            f[i*pre[j]]=pre[j];
            if(i%pre[j]==0)break;
        }
    }
}

ll fast(ll x,ll n)
{
    ll ans=1;
    while(n)
    {
        if(n&1)ans=(ans*x)%mod;
        x*=x;x%=mod;
        n>>=1;
    }
    return ans%mod;
}

ll sum[N<<2],col[N<<2];

void up(int pos)
{
    sum[pos]=sum[pos<<1]+sum[pos<<1|1];
}

void down(int pos)
{
    col[pos<<1]+=col[pos];
    col[pos<<1|1]+=col[pos];
    col[pos]=0;
}

void build(int l,int r,int pos)
{
    if(l==r)
    {
        scanf("%lld",&sum[pos]);col[pos]=0;
        return ;
    }
    int m=(l+r)>>1;
    build(lson);build(rson);
    up(pos);
}


void update1(int L,int R,int l,int r,int pos)
{
    if(sum[pos]==r-l+1)return ;
    if(L<=l&&r<=R)
    {
        col[pos]++;
        return ;
    }
    down(pos);
    int m=(l+r)>>1;
    if(L<=m)update1(L,R,lson);
    if(R>m)update1(L,R,rson);
    up(pos);
}

void update2(int L,int R,int l,int r,int pos)
{
    if(sum[pos]==r-l+1)return ;

    if(L<=l&&r<=R&&col[pos])
    {
        col[pos]--;return ;
    }
    if(l==r)
    {
        sum[pos]=sum[pos]/f[sum[pos]]%mod;return ;
    }
    down(pos);
    int m=(l+r)>>1;
    if(L<=m)update2(L,R,lson);
    if(R>m)update2(L,R,rson);
    up(pos);
}

ll query(int x,int l,int r,int pos)
{
    if(sum[pos]==r-l+1)return 1;
    if(l==r)
    {
        return  sum[pos]*fast(f[sum[pos]],col[pos])%mod;
    }
    down(pos);
    int m=(l+r)>>1;
    if(x<=m)return query(x,lson);
    else return query(x,rson);
}

int main()
{
    init();
    int n,m;
    RII(n,m);
    build(1,n,1);
    int q,a,b;
    while(m--)
    {
        RI(q);
        if(q==1)
        {
            RII(a,b);
            update1(a,b,1,n,1);
        }
        else if(q==2)
        {
            RII(a,b);
            update2(a,b,1,n,1);
        }
        else if(q==3)
        {
           RI(a);cout<<query(a,1,n,1)<<endl;
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/10890618.html