Codeforces 498D Traffic Jams in the Land | 线段树

题目大意:

给坐标轴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
",query(1,x,y-1,0));
71     }
72     return 0;
73 }
原文地址:https://www.cnblogs.com/mrsheep/p/7873537.html