「CF498D」Traffic Jams in the Land
题解
显然这是数据结构题。。。
线段树可以解决,发现y<=6,所以只要在线段树每个节点记录t[x],res[x]表示从x(mod 60)时刻开始,在这一段的堵车时间,以及最后时刻(mod 60)
然后合并比较显然。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#include<cstdio> #include<cmath> #include<ctime> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<set> #define ll long long #define mod 1000000007 #define inf 1000000000 using namespace std; int read() { int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m; int a[100005]; struct seg{ int l,r,t[60],res[60]; seg(){} seg(int _l,int _r,int x):l(_l),r(_r){ for(int i=0;i<60;i++) if(i%x==0)t[i]=1,res[i]=2; else t[i]=0,res[i]=1; } }t[400005]; seg merge(seg a,seg b) { seg t; t.l=a.l;t.r=b.r; for(int i=0;i<60;i++) { t.t[i]=a.t[i]+b.t[a.res[i]]; t.res[i]=(a.res[i]+b.res[a.res[i]%60])%60; } return t; } void build(int k,int l,int r) { t[k].l=l;t[k].r=r; if(l==r){t[k]=seg(l,r,a[l]);return;} int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); t[k]=merge(t[k<<1],t[k<<1|1]); } seg query(int k,int x,int y) { int l=t[k].l,r=t[k].r,mid=(l+r)>>1; if(x==l&&y==r)return t[k]; if(y<=mid)return query(k<<1,x,y); else if(x>mid)return query(k<<1|1,x,y); else return merge(query(k<<1,x,mid),query(k<<1|1,mid+1,y)); } void change(int k,int x,int val) { int l=t[k].l,r=t[k].r,mid=(l+r)>>1; if(l==r){t[k]=seg(l,r,val);return;} if(x<=mid)change(k<<1,x,val); else change(k<<1|1,x,val); t[k]=merge(t[k<<1],t[k<<1|1]); } int main() { n=read(); for(int i=1;i<=n;i++)a[i]=read(); build(1,1,n); m=read(); char opt[4]; int x,y; while(m--) { scanf("%s",opt); x=read();y=read(); if(opt[0]=='C')change(1,x,y); else printf("%d\n",query(1,x,y-1).t[0]+y-x); } return 0; } |
对不起我坑了你