题解 | 小沙的算数

小沙的算数

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;
    }
}

全部评论

相关推荐

整顿职场的柯基很威猛:这种不可怕,最可怕的是夹在一帮名校里的二本选手,人家才是最稳的。
点赞 评论 收藏
分享
我是小红是我:学校换成中南
点赞 评论 收藏
分享
在努力的外卷侠很靠谱:怎么,大家都没保底吗?我这美团已经入职了,不说了,系统派单了。
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务