小花梨的数组

博客内容包含题解和标程,虽信息简略,但聚焦于解题思路与标准程序的呈现,属于信息技术解题相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
题解:
在这里插入图片描述
标程:

#include<bits/stdc++.h>
#define lc ((o) << 1)
#define rc ((o) << 1 | 1)
using namespace std;
typedef long long ll;
typedef pair<int, int> Pair;
const int maxn = 1e5 + 10;
const int MOD = 1e9 + 7;
int Mul[maxn << 2], Div[maxn << 2], a[maxn];
vector<int>factor[maxn], suf[maxn];
bool vis[maxn];
int prime[1010], tot;
void init(int n)//找出所有素数
{
    for(int i = 2; i <= n; i++)if(!vis[i])
    {
        prime[++tot] = i;
        for(ll j = (ll)i * i; j <= n; j += i)vis[j] = 1;
    }
}
void pushdown(int o, int l, int r)//标记下放,重点
{
    if(Mul[o] || Div[o])
    {
        if(Mul[lc] >= Div[o])Mul[lc] -= Div[o];//如果先乘后除,除把乘抵消
        else Div[lc] += (Div[o] - Mul[lc]), Mul[lc] = 0;
        if(Mul[rc] >= Div[o])Mul[rc] -= Div[o];
        else Div[rc] += (Div[o] - Mul[rc]), Mul[rc] = 0;
        Mul[lc] += Mul[o];//乘法运算正常加
        Mul[rc] += Mul[o];
        Mul[o] = Div[o] = 0;
    }
}
void update(int o, int l, int r, int L, int R, int tree[], int op)
{
    if(L <= l && R >= r)
    {
        if(op == 1)tree[o]++;//乘法运算正常加
        else
        {
            if(Mul[o])Mul[o]--;//如果先乘后除,除把乘抵消
            else tree[o]++;
        }
        return;
    }
    pushdown(o, l, r);
    int m = (l + r) / 2;
    if(L <= m)update(lc, l, m, L, R, tree, op);
    if(R > m)update(rc, m + 1, r, L, R, tree, op);
}
void query(int o, int l, int r, int x, int& divnum, int& mulnum)
{
    if(l == r)
    {
        divnum = Div[o];
        mulnum = Mul[o];
        return;
    }
    pushdown(o, l, r);
    int m = (l + r) / 2;
    if(x <= m)query(lc, l, m, x, divnum, mulnum);
    else query(rc, m + 1, r, x, divnum, mulnum);
}
ll pow(ll a, ll b, ll m)
{
    ll ans = 1;
    while(b)
    {
        if(b & 1)ans = a * ans % m;
        b >>= 1;
        a = a * a % m;
    }
    return ans;
}
int main()
{
    int n, m;
    init(1000);
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);int x = a[i];
        for(int j = 1; j <= tot && prime[j] * prime[j] <= x; j++)
            while(x % prime[j] == 0)x /= prime[j], factor[i].push_back(prime[j]);
            if(x != 1)factor[i].push_back(x);//因为x>=4才能执行上面的循环
       // x = a[i];
        //for(int j = 0; j < factor[i].size(); j++)cout<<factor[i][j]<<" ";cout<<endl;
    }
    for(int i = 1; i <= m; i++)
    {
        int op, l, r;
        scanf("%d", &op);
        if(op == 1)
        {
            scanf("%d%d", &l, &r);
            update(1, 1, n, l, r, Mul, 1);
        }
        else if(op == 2)
        {
            scanf("%d%d", &l, &r);
            update(1, 1, n, l, r, Div, 2);
        }
        else if(op == 3)
        {
            scanf("%d", &l);
            int divnum = 0, mulnum = 0;
            query(1, 1, n, l, divnum, mulnum);
            //cout<<divnum<<" "<<mulnum<<endl;
            if(divnum >= factor[l].size())puts("1");
            else
            {
                int ans = 1, tmp = factor[l][divnum];
                //cout<<tmp<<endl;
                for(int i = divnum; i < factor[l].size(); i++)
                    ans *= factor[l][i];
                ans = (ll)ans * pow(tmp, mulnum, MOD) % MOD;
                printf("%d\n", ans);
            }
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值