题解 | 小沙的算数

小沙的算数

https://ac.nowcoder.com/acm/contest/23477/F

  • 写一个极简版的,思路:保存每一个有效数区间 例如 2+432+53+2 那就有4个区间要保存,分别为2,432,53,2用一个数组保存他们对应的值,考虑到一个区间中所有元素都要能查询到这个值,可以用两种方法

    1. 运用并查集,将乘法块中的每个数都指向其第一个元素
    1. 运用一个指针数组,pos[i]=cnt,来指向;

这里我们选用方法2 ,对于最开始有效块的处理是需要注意的,想了挺久如何简化这个代码

for(int i=2;i<=n;i++){
     if(s[i-1]=='*'){
          pos[i]=cnt;
          num[cnt]=num[cnt]*a[i]%mod;
     }
     else{
          num[++cnt]=a[i];
          pos[i]=cnt;
     }
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int N = 1e6+8;
char s[N];
ll num[N],pos[N],n,q,a[N];
ll ksm(ll a, ll b) {
    ll ans = 1;
    for (; b; b >>= 1, (a *= a) %= mod)
        if (b & 1)(ans *= a) %= mod;
    return ans;
}
int main()
{
    cin>>n>>q;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)cin>>a[i];
    int cnt=1;
    num[1]=a[1];
    pos[1]=1;
    for(int i=2;i<=n;i++){
        if(s[i-1]=='*'){
            pos[i]=cnt;
            num[cnt]=num[cnt]*a[i]%mod;
        }
        else{
            num[++cnt]=a[i];
            pos[i]=cnt;
        }
    }
    ll ans = 0,x=0,y=0;
    for(int i=1;i<=cnt;i++)ans=(ans+num[i])%mod;
    while(q--){
        cin>>x>>y;
        ans=(ans-num[pos[x]]+mod)%mod;
        num[pos[x]]=num[pos[x]]*ksm(a[x],mod-2)%mod*y%mod;
        ans=(ans+num[pos[x]])%mod;
        a[x]=y;
        cout<<ans<<endl;
    }
}

全部评论

相关推荐

11-27 17:35
已编辑
蚌埠坦克学院 C++
深信服 后台开发 n×12
点赞 评论 收藏
分享
10-25 00:32
香梨想要offer:感觉考研以后好好学 后面能乱杀,目前这简历有点难
点赞 评论 收藏
分享
offer多多的六边形战士很无语:看了你的博客,感觉挺不错的,可以把你的访问量和粉丝数在简历里提一下,闪光点(仅个人意见)
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务