Codeforces

来源:互联网 发布:在淘宝上买手机安全吗 编辑:程序博客网 时间:2024/06/16 00:55

Traffic Jams in the Land

题目链接

分类dp number theory data structures

1.题意概述

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

2.解题思路

  • 注意到2ai6,那么实际上时间状态最多只有60种(是区间[2,6]的最小公倍数),区间问题,我们可以用线段树维护延时延时,因为有60种状态,因此我们要开60颗线段树,查洵时候按要求。
  • 一个大trick:因为线段树至少4倍,内存,还要乘以60倍,因此特别要注意内存限制。我以前的板还对每个节点存了左端点和右端点,无形之中增加了两倍内存,容易Memory Limited Ecxeed

3.AC代码

class SegmentTree {public:#define lson (root << 1)#define rson (root << 1 | 1)#define lent (t[root].r - t[root].l + 1)#define lenl (t[lson].r - t[lson].l + 1)#define lenr (t[rson].r - t[rson].l + 1)    int t[maxn << 2][N];    void pushup(int root) {        rep(i, 0, N) {            int x = (i + t[lson][i]) % N;            t[root][i] = t[lson][i] + t[rson][x];        }    }    void build(int l, int r, int root) {        if (l == r) {            int x;            scanf("%d", &x);            rep(i, 0, N) t[root][i] = (i % x) ? 1 : 2;            return;        }        int mid = l + r >> 1;        build(l, mid, lson);        build(mid + 1, r, rson);        pushup(root);    }    void update(int a, int b, int l, int r, int val, int root) {        if (l <= a && b <= r) {            rep(i, 0, N) t[root][i] = (i % val) ? 1 : 2;            return;        }        int mid = a + b >> 1;        if (l <= mid) update(a, mid, l, r, val, lson);        if (r > mid) update(mid + 1, b, l, r, val, rson);        pushup(root);    }    int query(int a, int b, int l, int r, int x, int root) {        if (l <= a && b <= r)            return x + t[root][x % N];        int mid = a + b >> 1;        if (l <= mid) x = query(a, mid, l, r, x, lson);        if (r > mid) x = query(mid + 1, b, l, r, x, rson);        return x;    }#undef lenr#undef lenl#undef lent#undef rson#undef lson} T;inline void solve() {    int n, q;    scanf("%d", &n);    T.build(1, n, 1);    scanf("%d", &q);    while (q--) {        char op[2];        int x, y;        scanf("%s%d%d", op, &x, &y);        if (op[0] == 'C') T.update(1, n, x, x, y, 1);        else printf("%d\n", T.query(1, n, x, y - 1, 0, 1));    }}
原创粉丝点击