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

Posted wls001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ UNR #1火车管理 可持久化线段树相关的知识,希望对你有一定的参考价值。

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

技术分享图片
 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
",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火车管理 可持久化线段树的主要内容,如果未能解决你的问题,请参考以下文章

[UOJ218]火车管理

UOJ #218. UNR #1火车管理

uoj#218. UNR #1火车管理

UOJ#217. UNR #1奇怪的线段树(广义线段树性质+上下界最小流)

uoj#388. UNR #3配对树(线段树合并)

UOJ388 [UNR #3] 配对树