• 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,很小,而且这些数的最小公倍数最大只有60,那么对于每一个节点,我们开一个tim[60]的数组,tim[j]维护在时刻 j ,通过这段区间需要的时间。

    那么区间合并的时候就是 j 从0~59枚举,这个区间的第 j 个时刻花费的时间等于左区间的从 j 时刻花费的时间x,加上右区间从j + x时刻花费的时间。于是这题就完事啦。

    时间复杂度O(mlogn * 60)。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 using namespace std;
     12 #define enter puts("") 
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 1e5 + 5;
     21 inline ll read()
     22 {
     23   ll ans = 0;
     24   char ch = getchar(), last = ' ';
     25   while(!isdigit(ch)) {last = ch; ch = getchar();}
     26   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
     27   if(last == '-') ans = -ans;
     28   return ans;
     29 }
     30 inline void write(ll x)
     31 {
     32   if(x < 0) x = -x, putchar('-');
     33   if(x >= 10) write(x / 10);
     34   putchar(x % 10 + '0');
     35 }
     36 
     37 int n, m;
     38 char s[2];
     39 
     40 struct Tree
     41 {
     42     int l, r;
     43     int tim[65];
     44 }t[maxn << 2];
     45 void pushup(int now)
     46 {
     47     for(int i = 0; i < 60; ++i)
     48         t[now].tim[i] = t[now << 1].tim[i] + t[now << 1 | 1].tim[(i + t[now << 1].tim[i]) % 60];
     49 }
     50 void build(int L, int R, int now)
     51 {
     52     t[now].l = L; t[now].r = R;
     53     if(L == R)
     54     {
     55         int x = read();
     56         for(int i = 0; i < 60; ++i)
     57             if(!(i % x)) t[now].tim[i] = 2;
     58             else t[now].tim[i] = 1;
     59         return;
     60     }
     61     int mid = (L + R) >> 1;
     62     build(L, mid, now << 1);
     63     build(mid + 1, R, now << 1 | 1);
     64     pushup(now);
     65 }
     66 void update(int idx, int d, int now)
     67 {
     68     if(t[now].l == t[now].r)
     69     {
     70         for(int i = 0; i < 60; ++i)
     71             if(!(i % d)) t[now].tim[i] = 2;
     72             else t[now].tim[i] = 1;        
     73         return;
     74     }
     75     int mid = (t[now].l + t[now].r) >> 1;
     76     if(idx <= mid) update(idx, d, now << 1);
     77     else update(idx, d, now << 1 | 1);
     78     pushup(now);
     79 }
     80 int query(int L, int R, int now, int Tim)
     81 {
     82     if(t[now].l == L && t[now].r == R) return t[now].tim[Tim % 60];
     83     int mid = (t[now].l + t[now].r) >> 1;
     84     if(R <= mid) return query(L, R, now << 1, Tim);
     85     else if(L > mid) return query(L, R, now << 1 | 1, Tim);
     86     else 
     87     {
     88         int ret = query(L, mid, now << 1, Tim);
     89         ret += query(mid + 1, R, now << 1 | 1, (Tim + ret) % 60);
     90         return ret;
     91     }
     92 }
     93 
     94 int main()
     95 {
     96     n = read();
     97     build(1, n, 1);
     98     m = read();
     99     for(int i = 1; i <= m; ++i)
    100     {
    101         scanf("%s", s);
    102           if(s[0] == 'C')
    103         {
    104               int x = read(), d = read();
    105               update(x, d, 1);
    106         }
    107           else
    108         {
    109               int L = read(), R = read();
    110               write(query(L, R - 1, 1, 0)); enter;    //别忘 R - 1 
    111         }
    112     }
    113   return 0;
    114 }
    View Code
  • 相关阅读:
    [51nod] 1301 集合异或和
    [BZOJ] 1088: [SCOI2005]扫雷Mine
    [LUOGU] P4251 [SCOI2015]小凸玩矩阵
    8.21模拟赛
    [BZOJ] 3163: [Heoi2013]Eden的新背包问题
    [BZOJ] 1001: [BeiJing2006]狼抓兔子
    【NOIP2017提高A组冲刺11.8】好文章
    [BZOJ] 1520: [POI2006]Szk-Schools
    [BZOJ] 1877: [SDOI2009]晨跑
    day23(事务管理)
  • 原文地址:https://www.cnblogs.com/mrclr/p/9784569.html
Copyright © 2020-2023  润新知