2022牛客寒假算法基础集训营2,小沙的数数(分块,逆元)

传送门
在这里插入图片描述
思路:

首先对题意要有深刻理解,由于运算是有优先级的,且我们发现每一个+会区分开一段区间,每个区间的值互不干扰,所以我们可以提前将每一个区间的信息整合到一个值里面,然后进行计算,也就是分块的思想(块内乘积,块间加减),首先预处理第一块:第1个数字在第1块里,第一块的值是a[1],最后修改的过程中,定位到所要修改块的位置pos,之后改变块内的值,然后重新计算新值即可

代码:

#include<iostream>
#define int long long

using namespace std;
const int N=1000010,mod=1e9+7;
int a[N],b[N];
int n,q;
int ans[N];
char c[N];

int qmi(int a,int b){
    int res=1;
    while(b){
        if(b&1)res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

int inv(int a){
    return qmi(a,mod-2);
}

signed  main(){
    cin>>n>>q;
    cin>>(c+1);
    for(int i=1;i<=n;i++)
        cin>>a[i],ans[i]=1;
        
    //预处理第一块:第1个数字在第1块里,第一块的值是a[1]
    b[1]=1;
    ans[1]=a[1];
    
    int now=1;
    for(int i=1;i<=n-1;i++){
        //遇到'+',进入下一块
        if(c[i]=='+')now++;
        //第now块的值是ans[now]
        ans[now]=ans[now]*a[i+1]%mod;
        //第(i+1)个数字在第now块里
        b[i+1]=now;
    }
    int res=0;
    for(int i=1;i<=now;i++)
        res=(res+ans[i])%mod;
        
    while(q--){
        int x,y;
        cin>>x>>y;
        
        //修改的是第pos块的数据,要把old修改为y
        int pos=b[x],old=a[x];
        int en=ans[pos];
        ans[pos]=ans[pos]*inv(old)%mod*y%mod;
        int change=((ans[pos]-en)%mod+mod)%mod;
        res=(res+change)%mod;
        
        //别忘记
        a[x]=y;
        
        cout<<res<<endl;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值