[題解]codeforces498d Traffic Jams in the Land

題目:戳這裏

Solution

線段樹每個節點維護60個值,分別是走到該區間左端時時間爲i時該區間所用的時間,因爲題目中2<=y<=6,2到6的最小公倍數爲60,則走過的時間在判斷是否堵車是可以mod 60。

代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn=100010;
struct Data{
    int t[60];
    Data(){memset(t,0,sizeof t);}
};
struct Segment_Tree{
    #define lc x<<1
    #define rc x<<1|1
    int L[maxn<<2],R[maxn<<2];
    Data res[maxn<<2];
    void update(int x){
        for(int i=0;i<60;i++)
            res[x].t[i]=res[lc].t[i]+res[rc].t[(i+res[lc].t[i])%60];
    }
    void Build(int x,int *a,int l,int r){
        if((L[x]=l)==(R[x]=r)){
            for(int i=0;i<60;i++)
                if(i%a[l])res[x].t[i]=1;
                else res[x].t[i]=2;
            return;
        }
        int mid=(l+r)>>1;
        Build(lc,a,l,mid);Build(rc,a,mid+1,r);
        update(x);
    }
    void Change(int x,int pos,int val){
        if(L[x]==R[x]){
            for(int i=0;i<60;i++)
                if(i%val)res[x].t[i]=1;
                else res[x].t[i]=2;
            return;
        }
        int mid=(L[x]+R[x])>>1;
        if(pos<=mid)Change(lc,pos,val);
        else Change(rc,pos,val);
        update(x);
    }
    Data Query(int x,int l,int r){
        if(L[x]>=l&&R[x]<=r)return res[x];
        int mid=(L[x]+R[x])>>1;
        Data temp,ls,rs;
        if(l<=mid&&r>mid){
            ls=Query(lc,l,r);rs=Query(rc,l,r);
            for(int i=0;i<60;i++)
                temp.t[i]=ls.t[i]+rs.t[(i+ls.t[i])%60];
            return temp;
        }
        else if(l<=mid)return Query(lc,l,r);
        else return Query(rc,l,r);
    }
}tree;
int n,m,a[maxn];

int main(){ 
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    tree.Build(1,a,1,n);
    scanf("%d",&m);
    while(m--){
        char opt[5];int x,y;
        scanf("%s%d%d",opt,&x,&y);
        if(opt[0]=='A')printf("%d\n",tree.Query(1,x,y-1).t[0]);
        else if(opt[0]=='C')tree.Change(1,x,y);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章