[题目链接] (https://codeforc.es/contest/498/problem/D)
普通线段树题目,维护t时刻到达该点的信息。
#include<bits/stdc++.h>
#define m (l+r)/2
#define ls o*2
#define rs o *2+1
using namespace std;
const int maxn = 1e5+10;
int tr[maxn*4][60] , n ;
void build(int o,int l,int r)
{
if(l==r)
{
int a;
scanf("%d",&a);
for(int i=0;i<60;i++)
tr[o][i] = 1 + (i%a==0);
return ;
}
build(ls,l,m);
build(rs,m+1,r);
for(int i=0;i<60;i++)
tr[o][i] = tr[ls][i] + tr[rs][(i+tr[ls][i])%60];
}
void up(int o,int l,int r,int p,int v)
{
if(l==r)
{
for(int i=0;i<60;i++)
tr[o][i] = 1 + (i%v==0);
return;
}
if(p>m) up(rs,m+1,r,p,v);
else up(ls,l,m,p,v);
for(int i=0;i<60;i++)
tr[o][i] = tr[ls][i] + tr[rs][(i+tr[ls][i])%60];
}
int qu(int o,int l,int r,int ql,int qr,int t)
{
if(ql<=l&&qr>=r)
return tr[o][t];
int ans = 0;
if(ql<=m) ans += qu(ls,l,m,ql,qr,(t+ans)%60);
if(qr>m) ans += qu(rs,m+1,r,ql,qr,(t+ans)%60);
return ans ;
}
int main()
{
scanf("%d",&n);
build(1,1,n);
int q;scanf("%d",&q);
char s;
int l,r,p,v;
for(int i=1;i<=q;i++)
{
cin>>s;
if(s=='A'){
scanf("%d%d",&l,&r);
printf("%d\n",qu(1,1,n,l,r-1,0));
}
if(s=='C'){
scanf("%d%d",&p,&v);
up(1,1,n,p,v);
}
}
}