Traffic Jams in the Land(线段树好题)

Traffic Jams in the Land

CodeForces - 498D

  Some country consists of (n?+?1) cities, located along a straight highway. Let‘s number the cities with consecutive integers from 1 to n?+?1 in the order they occur along the highway. Thus, the cities are connected by n segments of the highway, the i-th segment connects cities number i and i?+?1. Every segment of the highway is associated with a positive integer ai?>?1 — the period of traffic jams appearance on it.

In order to get from city x to city y (x?<?y), some drivers use the following tactics.

Initially the driver is in city x and the current time t equals zero. Until the driver arrives in city y, he perfors the following actions:

  • if the current time t is a multiple of ax, then the segment of the highway number x is now having traffic problems and the driver stays in the current city for one unit of time (formally speaking, we assign t?=?t?+?1);
  • if the current time t is not a multiple of ax, then the segment of the highway number x is now clear and that‘s why the driver uses one unit of time to move to city x?+?1 (formally, we assign t?=?t?+?1 and x?=?x?+?1).

You are developing a new traffic control system. You want to consecutively process qqueries of two types:

  1. determine the final value of time t after the ride from city x to city y (x?<?y) assuming that we apply the tactics that is described above. Note that for each query t is being reset to 0.
  2. replace the period of traffic jams appearing on the segment number x by value y(formally, assign ax?=?y).

Write a code that will effectively process the queries given above.

Input

The first line contains a single integer n (1?≤?n?≤?105) — the number of highway segments that connect the n?+?1 cities.

The second line contains n integers a1,?a2,?...,?an (2?≤?ai?≤?6) — the periods of traffic jams appearance on segments of the highway.

The next line contains a single integer q (1?≤?q?≤?105) — the number of queries to process.

The next q lines contain the descriptions of the queries in the format cxy (c — the query type).

If c is character ‘A‘, then your task is to process a query of the first type. In this case the following constraints are satisfied: 1?≤?x?<?y?≤?n?+?1.

If c is character ‘C‘, then you need to process a query of the second type. In such case, the following constraints are satisfied: 1?≤?x?≤?n, 2?≤?y?≤?6.

Output

For each query of the first type output a single integer — the final value of time t after driving from city x to city y. Process the queries in the order in which they are given in the input.

Examples

Input

102 5 3 2 3 5 3 4 2 410C 10 6A 2 6A 1 3C 3 4A 3 11A 4 9A 5 6C 7 3A 8 10A 2 5

Output

53146244题意:某个国家有(n+1)(n+1)个城市(1≤n≤10^5),城市之间有高速公路,其中第ii段高速公路是从城市i通往城市(i+1)的,而且第i条道路有一个属性值ai(2≤ai≤6)表示这段城市的拥堵状态,当我们要从城市x到城市y时候,定义时刻t从0开始,如果当前时刻t是ax的倍数,那么当前车辆就不能行驶,只能停在原地,等待当前这一秒过去(相当于从x到y需要花费2秒),否则花费1秒。现在有两类操作,q(1≤q≤10^5)次查询: 
    • 1 x y查询从城市x到城市y所需要耗费的时间;
    • 2 x y修改第x个城市的拥堵值ax为y。

题解:因为题目给出2?≤?y?≤?6,而2-6的最小公倍数是60,相当于第0s进入和第60s进入某一个城市花费的时间相同,所以可以以60为一个周期,对每一个结点创建一个大小为60的时间数组,记录从0-59任何一个时间进入该结点所花费的时间。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6 const int maxn=2e5+10;
  7 struct node{
  8     int l;
  9     int r;
 10     int val;
 11     int t[61];
 12 }e[maxn<<2];
 13 int a[maxn];
 14 void pushup(int cur)//注意!!
 15 {
 16     for(int i=0;i<60;i++)
 17     {
 18         int temp=e[cur<<1].t[i];//左儿子当前时间进入需要花费的时间
 19         int nex=(i+temp)%60;//右儿子需要的时间为左儿子花费的时间加上进入左儿子的初始时间
 20         e[cur].t[i]=temp+e[cur<<1|1].t[nex];
 21     }
 22 }
 23 void build(int l,int r,int cur)
 24 {
 25     e[cur].l=l;
 26     e[cur].r=r;
 27     if(l==r)//对每一个结点创建一个时间数组记录任何时间进入的花费
 28     {
 29         for(int i=0;i<60;i++)
 30         {
 31             if(i%a[l]==0)
 32             {
 33                 e[cur].t[i]=2;
 34             }
 35             else
 36                 e[cur].t[i]=1;
 37         }
 38         return;
 39     }
 40     int mid=(l+r)/2;
 41     build(l,mid,cur<<1);
 42     build(mid+1,r,cur<<1|1);
 43     pushup(cur);
 44 }
 45 void update(int tar,int val,int cur)
 46 {
 47     if(e[cur].l==e[cur].r)
 48     {
 49         a[tar]=val;
 50         for(int i=0;i<60;i++)
 51         {
 52             if(i%a[tar]==0)
 53             {
 54                 e[cur].t[i]=2;
 55             }
 56             else
 57                 e[cur].t[i]=1;
 58         }
 59         return;
 60     }
 61     int mid=(e[cur].l+e[cur].r)/2;
 62     if(tar<=mid)
 63         update(tar,val,cur<<1);
 64     else
 65         update(tar,val,cur<<1|1);
 66     pushup(cur);
 67 }
 68 int query(int pl,int pr,int cur,int t)
 69 {
 70     if(pl<=e[cur].l&&e[cur].r<=pr)
 71     {
 72         return t+e[cur].t[t%60];
 73     }
 74     int mid=(e[cur].l+e[cur].r)/2;
 75     if(pl<=mid)
 76         t=query(pl,pr,cur<<1,t);
 77     if(pr>mid)
 78         t=query(pl,pr,cur<<1|1,t);
 79 return t;
 80 }
 81 int main()
 82 {
 83     int n;
 84     cin>>n;
 85     for(int i=1;i<=n;i++)
 86         scanf("%d",&a[i]);
 87     build(1,n,1);
 88     int q,x,y;
 89     char op[10];
 90     cin>>q;
 91     while(q--)
 92     {
 93         scanf("%s %d%d",op,&x,&y);
 94         if(op[0]==‘C‘)
 95         {
 96             update(x,y,1);
 97         }
 98         if(op[0]==‘A‘)
 99         {
100             int res=query(x,y-1,1,0);
101             printf("%d\n",res);
102         }
103     }
104 return 0;
105 }

原文地址:https://www.cnblogs.com/1013star/p/9597530.html

时间: 2024-11-04 02:34:21

Traffic Jams in the Land(线段树好题)的相关文章

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 us

CF498D Traffic Jams in the Land

嘟嘟嘟 题面:有n条公路一次连接着n + 1个城市,每一条公路有一个堵塞时刻a[i],如果当前时间能被a[i]整除,那么通过这条公路需要2分钟:否则需要1分钟. 现给出n条公路的a[i],以及m次操作.每一次操作:1.C x d:将第x条的堵塞时刻改为d.2.A x y:询问从城市x到城市y的所需时间. 这能想到是一个线段树的题,虽然做过好多道线段树的题,但遇到这种思路比较新奇的题,独立的想出来还是有一点困难. 于是稍微参照了一下题解. 我们观察一下a[i],2 <= a[i] <= 6,很小

HDU 4893 线段树裸题

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2512    Accepted Submission(s): 751 Problem Description Recently, Doge got a funny birthday present from his new friend, Pro

HDU 4027 Can you answer these queries? 线段树裸题

题意: 给定2个操作 0.把区间的每个数sqrt 2.求和 因为每个数的sqrt次数很少,所以直接更新到底,用个标记表示是否更新完全(即区间内的数字只有0,1就不用再更新了) #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<set> #incl

[POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]

可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> using namespace std; int n,q,tot,a[110000]; in

POJ 3468 线段树裸题

这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解. 然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了ACdreamer的模板,在此基础上自己用宏定义来精简了一下代码: 1 #include<cstdio> 2 typedef long long LL; 3 #define root int rt, int l, int r 4 #define lson rt*2, l, mid 5 #define

[ACM] Color the ball [线段树水题][数组开大]

Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色.但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗? Input 每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N).  当N

poj 2182 Lost Cows(线段树经典题)

题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9152   Accepted: 5879 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, th

LA 2191电位计(线段树模板题)

线段树模板题,没啥好说的.....注意输出是case之间空一行就行.........之前一直没注意,一直wa 代码如下: #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #includ