码迷,mamicode.com
首页 > 其他好文 > 详细

【UOJ UNR #1】火车管理 可持久化线段树

时间:2018-09-18 22:44:15      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:class   close   span   sdi   src   lse   code   alt   for   

用可持久化线段树维护每个站的第一辆车和每个站的前一次更新的位置即可。

技术分享图片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define maxn 500005
 8 using namespace std;
 9 inline int read() {
10     int x=0,f=1;char ch=getchar();
11     for(;!isdigit(ch);ch=getchar()) if(ch==-) f=-1;
12     for(;isdigit(ch);ch=getchar()) x=x*10+ch-0;
13     return x*f;
14 }
15 struct data {
16     int s[2];
17     int tag,sum;
18 }t[maxn*100];
19 int n,m,ty,cnt,last,tmp[maxn],rt[maxn];
20 void pushup(int o) {t[o].sum=t[t[o].s[0]].sum+t[t[o].s[1]].sum;}
21 void pushdown(int o,int l,int r) {
22     if(!t[o].tag) return;
23     int mid=(l+r)>>1;
24     t[++cnt]=t[t[o].s[0]];
25     t[cnt].tag=t[o].tag;t[cnt].sum=(mid-l+1)*tmp[t[o].tag];t[o].s[0]=cnt;
26     t[++cnt]=t[t[o].s[1]];
27     t[cnt].tag=t[o].tag;t[cnt].sum=(r-mid)*tmp[t[o].tag];t[o].s[1]=cnt;
28     t[o].tag=0;
29 }
30 inline void add(int l,int r,int &o,int x,int L,int R,int ad){
31     if(!o) o=++cnt,t[o]=t[x];
32     if(L<=l&&R>=r){t[o].tag=ad;t[o].sum=(r-l+1)*tmp[ad];return;}
33     int gg=t[o].tag;
34     pushdown(o,l,r);
35     int mid=(l+r)>>1;
36     if(L<=mid) {if(!gg) t[o].s[0]=0; add(l,mid,t[o].s[0],t[x].s[0],L,R,ad);}
37     if(R>mid) {if(!gg) t[o].s[1]=0; add(mid+1,r,t[o].s[1],t[x].s[1],L,R,ad);}
38     pushup(o);
39 }
40 int query1(int l,int r,int o,int L,int R) {
41     if(L<=l&&R>=r) return t[o].sum;
42     int mid=(l+r)>>1;
43     pushdown(o,l,r);
44     int ans=0;
45     if(L<=mid) ans+=query1(l,mid,t[o].s[0],L,R);
46     if(R>mid) ans+=query1(mid+1,r,t[o].s[1],L,R);
47     return ans;
48 }
49 int query2(int l,int r,int o,int x) {
50     if(l==r) return t[o].tag;
51     int mid=(l+r)>>1;
52     pushdown(o,l,r);
53     if(x<=mid) return query2(l,mid,t[o].s[0],x);
54     else return query2(mid+1,r,t[o].s[1],x);
55 }
56 int main() {
57     n=read(),m=read(),ty=read();
58     for(int i=1;i<=m;i++) {
59         int tp=read();rt[i]=++cnt;t[rt[i]]=t[rt[i-1]];
60         if(tp==1) {
61             int l=(read()+last*ty)%n+1,r=(read()+last*ty)%n+1;
62             printf("%d\n",last=query1(1,n,rt[i],min(l,r),max(l,r)));
63         }
64         if(tp==2) {
65             int l=(read()+last*ty)%n+1,x=query2(1,n,rt[i],l);
66             if(x!=0) add(1,n,rt[i],rt[i-1],l,l,query2(1,n,rt[x-1],l));
67         }
68         if(tp==3) {
69             int l=(read()+last*ty)%n+1,r=(read()+last*ty)%n+1;
70             tmp[i]=read();
71             add(1,n,rt[i],rt[i-1],min(l,r),max(l,r),i);
72         }
73     }
74 }
View Code

 

【UOJ UNR #1】火车管理 可持久化线段树

标签:class   close   span   sdi   src   lse   code   alt   for   

原文地址:https://www.cnblogs.com/wls001/p/9671319.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!