CF498D Traffic Jams in the Land

gate

用时:40min(看题解了)

线段树,然而思路不太好想,考虑看题解
每个公路有一个拥堵值(a[i]),如果当前时间能被(a[i])整除,那么通过这条公路需要(2)分钟,否则需要(1)分钟,(2 le a[i] le 6)
由于(a[i])的范围很小,(lcm(a[i]))的最大值只有(60),所以可以把当前的时间对(60)取模。然后随便想想就出来了
维护(sum[now][i])表示节点(now)在时刻(i)需要花费的时间。
可以得到:(sum[now][i] = sum[ls][i] + sum[rs][(i+sum[ls][i])\%60])

注意,查询城市((l,r))相当于公路((l,r-1))
空间足够的话就开4倍吧,2倍RE了:(

(code)

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;

const int maxn = 4e5+10;
const int mod = 60;
int n,q,x,y,a[maxn],sum[maxn][70];
char s[10];

#define ls (now<<1)
#define rs (now<<1|1)
#define Mid (l+r>>1)

int read(){
    int x = 0,f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while('0' <= ch && ch <= '9'){
        x = x*10 + ch-'0';
        ch = getchar();
    }
    return x*f;
}

void pushup(int now){
    for(int i = 0;i < mod;i++)
        sum[now][i] = sum[ls][i] + sum[rs][(i+sum[ls][i])%mod];
}

void build(int l,int r,int now){
    if(l == r){
        for(int i = 0;i < mod;i++)
            sum[now][i] = 1 + (i%a[l]==0);
        return;
    }
    int mid = Mid;
    build(l,mid,ls);
    build(mid+1,r,rs);
    pushup(now);
}

void modify(int l,int r,int now,int x,int d){
    if(l == r){
        a[l] = d;
        for(int i = 0;i < mod;i++)
            sum[now][i] = 1 + (i%a[l]==0);
        return;
    }
    int mid = Mid;
    if(x <= mid) modify(l,mid,ls,x,d);
    else if(x >= mid+1) modify(mid+1,r,rs,x,d);
    pushup(now);
}

int query(int L,int R,int l,int r,int now,int t){
    if(L == l && R == r){
        return sum[now][t];
    }
    int mid = Mid;
    if(R <= mid) return query(L,R,l,mid,ls,t);
    else if(L >= mid+1) return query(L,R,mid+1,r,rs,t);
    else {
        int ret = query(L,mid,l,mid,ls,t);
        ret += query(mid+1,R,mid+1,r,rs,(t+ret)%mod);
        return ret;
    }
}

int main(){
    n = read();
    for(int i = 1;i <= n;i++)
        a[i] = read();
    build(1,n,1);
    q = read();
    while(q--){
        scanf("%s",s);
        x = read(), y = read();
        if(s[0] == 'A')
            printf("%d
",query(x,y-1,1,n,1,0));
        if(s[0] == 'C')
            modify(1,n,1,x,y);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/mogeko/p/13228967.html