列表

详情


NC231906. 大战水魔兽

描述

李逍遥终于迎来与拜月教主的决战,只见拜月教主召唤出了 n 只水魔兽,第 i 只的水魔兽的体力值为 .

李逍遥在寻找水魔兽的弱点,由于御剑术威力过大会消耗掉全身真气,因此他每次会选择一个区间 假想发动御剑术来查询此次造成的伤害值(并不会对水魔兽造成实质伤害).

对于区间 的水魔兽,御剑术的伤害值计算规则为:构造非空正整数序列 s 满足 ,则伤害值为 .

拜月教主也不甘示弱,他每次会挑选一个区间 和整数 x,使得区间 水魔兽的体力值变成 x 倍,即 .

由于李逍遥正忙着对付拜月教主,所以请你帮他计算伤害值。

输入描述

第一行输入两个整数  表示有 n 只水魔兽和 q 次操作.

第二行有 n 个整数 ,其中 表示第 i 只水魔兽的体力值.

接下来 q 行,每行第一个整数 op 表示操作类型.

则后面有两个整数 表示李逍遥对区间 的水魔兽假想发动御剑术的伤害值.

则后面有三个整数 表示拜月教主把区间 水魔兽的体力值变成 x 倍.

输出描述

对于每次御剑术操作,输出一个整数表示此次伤害值,由于结果可能很大,所以你只需要输出答案对 998244353 取模后的值.

示例1

输入:

10 10
3 2 4 8 8 7 8 4 8 10
1 1 7
1 1 3
1 6 10
2 1 2 2
1 5 6
1 1 7
2 1 2 2
1 1 1
1 2 10
1 1 7

输出:

34
9
30
13
38
7
52
42

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 1110ms, 内存消耗: 177904K, 提交时间: 2022-03-29 20:38:48

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+10;
const int maxm=1e7+10;
const ll mod=998244353;
ll sumv[maxn<<2],addv[maxn<<2],a[maxn],v,ans_sum,mind[maxm],val[maxm];
int ql,qr;

inline ll re(int x){
    if(x==1) return 0;
    return val[x];
}

inline void pushdown(int o,int L,int R){
    int M=(R+L)>>1;
    if(addv[o]){
        addv[o*2]+=addv[o];
        addv[o*2+1]+=addv[o];
        sumv[o*2]+=addv[o]*(M-L+1);
        sumv[o*2+1]+=addv[o]*(R-M);
        addv[o]=0;
    }
}

inline void pushup(int o){
    sumv[o]=sumv[o*2]+sumv[o*2+1];
}

void build(int o,int L,int R){
    int M=(L+R)>>1;
    if(L!=R){
        build(o*2,L,M);
        build(o*2+1,M+1,R);
        pushup(o);
    }
    else sumv[o]=a[L];
}

void add_tree(int o,int L,int R){
    if(ql<=L&&R<=qr){
        addv[o]+=v;
        sumv[o]+=1LL*(R-L+1)*v;
    }
    else{
        int M=(L+R)>>1;
        pushdown(o,L,R);
        if(ql<=M) add_tree(o*2,L,M);
        if(qr>M) add_tree(o*2+1,M+1,R);
        pushup(o);
    }
}

void query_tree(int o,int L,int R){
    if(ql<=L&&R<=qr){
        ans_sum+=sumv[o];
    }
    else{
        pushdown(o,L,R);
        int M=(L+R)>>1;
        if(ql<=M) query_tree(o*2,L,M);
        if(qr>M) query_tree(o*2+1,M+1,R);
        pushup(o);
    }
}

int main(){
	ios::sync_with_stdio(false);

	memset(mind,-1,sizeof(mind));
	mind[1] = 1;
    for(int i=2;i<maxm;i++) if(mind[i]==-1)
        for(int j=i;j<maxm;j+=i) if (mind[j]==-1)
            mind[j]=i;
    for(int i=2;i<maxm;i++) {
        int j=i/mind[i];
        val[i]=val[j]+mind[i];
    }
    //debug(val[15]);
	int n,q;scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);a[i]=re(a[i]);
    }
    build(1,1,n);
    while(q--){
        int op;scanf("%d%d%d",&op,&ql,&qr);
        if(op==1){
            ans_sum=0;
            query_tree(1,1,n);
            if(ans_sum==0) ans_sum=1;
            printf("%lld\n",ans_sum%mod);
        }
        else{
           int x;scanf("%d",&x);
            v=re(x);
            add_tree(1,1,n);
        }
    }
}

上一题