题目大意:
给坐标轴1~n的点,每个点有一个权值,从一个点走到下一个点需要1s,如果当前时间是权值的倍数就要多花1s
给出q组操作,C表示单点修改权值,A表示询问0时刻x出发到y的时间
题解:因为权值只有2,3,4,5,6,所以60是一个周期,我们维护一颗线段树,维护0到59时刻出发从l到r+1用的时间
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define N 100010 5 using namespace std; 6 struct node 7 { 8 int l,r,tim[65]; 9 }t[4*N]; 10 int n,q,a[N],x,y; 11 char s[N]; 12 void pushup(int p) 13 { 14 for (int i=0;i<60;i++) 15 t[p].tim[i]=t[2*p].tim[i]+t[2*p+1].tim[(t[2*p].tim[i]+i)%60]; 16 } 17 void build(int p,int l,int r) 18 { 19 t[p].l=l,t[p].r=r; 20 if (l!=r) 21 { 22 int mid=l+r>>1; 23 build(2*p,l,mid); 24 build(2*p+1,mid+1,r); 25 pushup(p); 26 } 27 else 28 for (int i=0;i<60;i++) 29 t[p].tim[i]=1+!(i%a[l]); 30 } 31 void modify(int p,int l,int k) 32 { 33 int ll=t[p].l,rr=t[p].r,mid=ll+rr>>1; 34 if (ll==l && ll==rr) 35 { 36 for (int i=0;i<60;i++) 37 t[p].tim[i]=1+!(i%k); 38 return; 39 } 40 if (l<=mid) modify(2*p,l,k); 41 else modify(2*p+1,l,k); 42 pushup(p); 43 } 44 int query(int p,int x,int y,int ti) 45 { 46 int ll=t[p].l,rr=t[p].r,mid=ll+rr>>1; 47 if (x==ll && y==rr) 48 return t[p].tim[ti%60]; 49 if (y<=mid) 50 return query(2*p,x,y,ti); 51 if (x>mid) return query(2*p+1,x,y,ti); 52 int tmp=query(2*p,x,mid,ti); 53 return tmp+query(2*p+1,mid+1,y,(ti+tmp)%60); 54 } 55 int main() 56 { 57 scanf("%d",&n); 58 for (int i=1;i<=n;i++) 59 scanf("%d",a+i); 60 a[n+1]=1; 61 build(1,1,n+1); 62 scanf("%d",&q); 63 while (q--) 64 { 65 scanf("%s",s); 66 scanf("%d%d",&x,&y); 67 if (s[0]==‘C‘) 68 modify(1,x,y); 69 else 70 printf("%d\n",query(1,x,y-1,0)); 71 } 72 return 0; 73 }
时间: 2024-10-11 19:55:10