bzoj2959: 长跑
2959: 长跑
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 194 Solved: 114
[Submit][Status][Discuss]
Description
某校开展了同学们喜闻乐见的阳光长跑活动。为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动。一时间操场上熙熙攘攘,摩肩接踵,盛况空前。
为了让同学们更好地监督自己,学校推行了刷卡机制。
学校中有n个地点,用1到n的整数表示,每个地点设有若干个刷卡机。
有以下三类事件:
1、修建了一条连接A地点和B地点的跑道。
2、A点的刷卡机台数变为了B。
3、进行了一次长跑。问一个同学从A出发,最后到达B最多可以刷卡多少次。具体的要求如下:
当同学到达一个地点时,他可以在这里的每一台刷卡机上都刷卡。但每台刷卡机只能刷卡一次,即使多次到达同一地点也不能多次刷卡。
为了安全起见,每条跑道都需要设定一个方向,这条跑道只能按照这个方向单向通行。最多的刷卡次数即为在任意设定跑道方向,按照任意路径从A地点到B地点能刷卡的最多次数。
Input
输入的第一行包含两个正整数n,m,表示地点的个数和操作的个数。
第二行包含n个非负整数,其中第i个数为第个地点最开始刷卡机的台数。
接下来有m行,每行包含三个非负整数P,A,B,P为事件类型,A,B为事件的两个参数。
最初所有地点之间都没有跑道。
每行相邻的两个数之间均用一个空格隔开。表示地点编号的数均在1到n之间,每个地点的刷卡机台数始终不超过10000,P=1,2,3。
Output
输出的行数等于第3类事件的个数,每行表示一个第3类事件。如果该情况下存在一种设定跑道方向的方案和路径的方案,可以到达,则输出最多可以刷卡的次数。如果A不能到达B,则输出-1。
Sample Input
9 31
10 20 30 40 50 60 70 80 90
3 1 2
1 1 3
1 1 2
1 8 9
1 2 4
1 2 5
1 4 6
1 4 7
3 1 8
3 8 8
1 8 9
3 8 8
3 7 5
3 7 3
1 4 1
3 7 5
3 7 3
1 5 7
3 6 5
3 3 6
1 2 4
1 5 5
3 3 6
2 8 180
3 8 8
2 9 190
3 9 9
2 5 150
3 3 6
2 1 210
3 3 6
10 20 30 40 50 60 70 80 90
3 1 2
1 1 3
1 1 2
1 8 9
1 2 4
1 2 5
1 4 6
1 4 7
3 1 8
3 8 8
1 8 9
3 8 8
3 7 5
3 7 3
1 4 1
3 7 5
3 7 3
1 5 7
3 6 5
3 3 6
1 2 4
1 5 5
3 3 6
2 8 180
3 8 8
2 9 190
3 9 9
2 5 150
3 3 6
2 1 210
3 3 6
Sample Output
-1
-1
80
170
180
170
190
170
250
280
280
270
370
380
580
HINT
数据规模及约定
对于100%的数据,m<=5n,任意时刻,每个地点的刷卡机台数不超过10000。N<=1.5×105
Source
题解:
http://blog.csdn.net/popoqqq/article/details/45741749
还有,此题卡常数。。。。。
code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 char ch; 8 bool ok; 9 void read(int &x){ 10 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; 11 for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); 12 if (ok) x=-x; 13 } 14 const int maxn=150005; 15 int n,m,v,op,a,b,anc[maxn],bel[maxn]; 16 int find(int x){return anc[x]==x?x:anc[x]=find(anc[x]);} 17 int find_(int x){return bel[x]==x?x:bel[x]=find_(bel[x]);} 18 struct lct{ 19 int son[maxn][2],fa[maxn],val[maxn],tot[maxn],sum[maxn],rev[maxn]; 20 int wh[maxn]; 21 void reverse(int x){ 22 if (x){ 23 rev[x]^=1; 24 if (wh[x]!=2) wh[x]^=1; 25 } 26 } 27 void pushdown(int x){if (rev[x]) swap(son[x][0],son[x][1]),reverse(son[x][0]),reverse(son[x][1]),rev[x]=0;} 28 void relax(int x){if (wh[x]!=2) relax(fa[x]); pushdown(x);} 29 void update(int x){ 30 sum[x]=tot[x]; 31 /*if (son[x][0])*/ sum[x]+=sum[son[x][0]]; 32 /*if (son[x][1])*/ sum[x]+=sum[son[x][1]]; 33 } 34 void rotate(int x){ 35 int y=fa[x],z=fa[y],d=wh[x],dd=wh[y]; 36 fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],wh[son[x][d^1]]=d,fa[x]=fa[y]; 37 if (dd!=2) son[z][dd]=x; 38 fa[y]=x,son[x][d^1]=y,update(y),update(x),wh[y]=d^1,wh[x]=dd; 39 } 40 void splay(int x){ 41 relax(x); 42 while (wh[x]!=2){ 43 if (wh[fa[x]]==2) rotate(x); 44 else if (wh[x]==wh[fa[x]]) rotate(fa[x]),rotate(x); 45 else rotate(x),rotate(x); 46 } 47 } 48 void access(int x){ 49 for (int p=0;x;fa[x]=find(fa[x]),x=fa[x]){ 50 splay(x); 51 if (son[x][1]) wh[son[x][1]]=2; 52 if (p) wh[p]=1; 53 son[x][1]=p,update(p=x); 54 } 55 } 56 void make_root(int x){access(x),splay(x),reverse(x);} 57 void link(int x,int y){make_root(x),fa[x]=y;} 58 int query(int x,int y){ 59 x=find(x),y=find(y); 60 make_root(x),access(y),splay(y); 61 return sum[y]; 62 } 63 void merge(int x,int y){ 64 anc[x]=y,pushdown(x); 65 if (x!=y) tot[y]+=tot[x]; 66 if (son[x][0]) merge(son[x][0],y); 67 if (son[x][1]) merge(son[x][1],y); 68 } 69 void build(int x,int y){ 70 x=find(x),y=find(y); 71 int tx=find_(x),ty=find_(y); 72 if (tx==ty) make_root(x),access(y),splay(y),merge(y,y); 73 else link(x,y),bel[tx]=ty; 74 } 75 void modify(int x,int v){ 76 int y=find(x); 77 make_root(y),tot[y]-=val[x],val[x]=v,tot[y]+=val[x],update(y); 78 } 79 }T; 80 int main(){ 81 read(n),read(m); 82 for (int i=1;i<=n;i++) anc[i]=i; 83 for (int i=1;i<=n;i++) bel[i]=i; 84 for (int i=1;i<=n;i++) read(v),T.wh[i]=2,T.modify(i,v); 85 for (int i=1;i<=m;i++){ 86 read(op),read(a),read(b); 87 if (op==1) T.build(a,b); 88 else if (op==2) T.modify(a,b); 89 else if (op==3){ 90 if (find_(a)==find_(b)) printf("%d\n",T.query(a,b)); 91 else puts("-1"); 92 } 93 } 94 return 0; 95 }