hdu 6039 Gear Up(dfs序+线段树)
题目链接:hdu 6039 Gear Up
题意:
给出一些齿轮,有些齿轮是边相连,也就是拥有相同的线速度,
有的齿轮是轴相连,也就是拥有相同的角速度,现在给某个齿轮一个速度,
求这些齿轮中的最大速度,同时还有修改操作,可以更改某个齿轮的半径大小
题解:
官方题解:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int i=(a);i<=(b);++i) 4 inline int RT(int l,int r){return l+r|l!=r;} 5 using namespace std; 6 7 const int N=1e5+7; 8 struct Node{ 9 int st,i,val; 10 Node(int a,int b,int c):st(a),i(b),val(c){} 11 }; 12 int g[N],v[N*2],nxt[N*2],ed,mx[N*4],lazy[N*4]; 13 int n,m,q,r[N],f[N],is[N],Rt[N],sp[N*2]; 14 int in[N],out[N],ll[N],rr[N],idx,a,b,c,cas; 15 vector<Node>G[N]; 16 17 int find(int x){return f[x]!=x?f[x]=find(f[x]):x;} 18 void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;} 19 20 void dfs(int x,int fa,int v,int rt) 21 { 22 in[x]=++idx,Rt[x]=rt,sp[idx]=v; 23 for(auto &it:G[x]) 24 { 25 if(it.st!=fa) 26 { 27 ll[it.i]=min(ll[it.i],idx+1); 28 dfs(it.st,x,v+it.val,rt); 29 rr[it.i]=max(rr[it.i],idx); 30 }else is[it.i]=1;//是否与父节点线连 31 } 32 out[x]=++idx,sp[idx]=v; 33 } 34 35 inline void PU(int l,int r) 36 { 37 int mid=l+r>>1; 38 mx[RT(l,r)]=max(mx[RT(l,mid)],mx[RT(mid+1,r)]); 39 } 40 inline void PD(int l,int r) 41 { 42 int rt=RT(l,r),mid=l+r>>1; 43 int ls=RT(l,mid),rs=RT(mid+1,r); 44 mx[ls]+=lazy[rt],lazy[ls]+=lazy[rt]; 45 mx[rs]+=lazy[rt],lazy[rs]+=lazy[rt]; 46 lazy[rt]=0; 47 } 48 49 void build(int l=1,int r=idx) 50 { 51 int rt=RT(l,r),mid=l+r>>1; 52 mx[rt]=-INT_MAX,lazy[rt]=0; 53 if(l==r){mx[rt]=sp[l];return;} 54 build(l,mid),build(mid+1,r),PU(l,r); 55 } 56 57 void update(int L,int R,int v,int l=1,int r=idx) 58 { 59 int rt=RT(l,r),mid=l+r>>1; 60 if(L<=l&&r<=R){mx[rt]+=v,lazy[rt]+=v;return;} 61 if(lazy[rt]!=0)PD(l,r); 62 if(L<=mid)update(L,R,v,l,mid); 63 if(R>mid)update(L,R,v,mid+1,r); 64 PU(l,r); 65 } 66 67 int ask(int L,int R,int l=1,int r=idx) 68 { 69 int rt=RT(l,r),mid=l+r>>1,ans=-INT_MAX; 70 if(L<=l&&r<=R)return mx[rt]; 71 if(lazy[rt]!=0)PD(l,r); 72 if(L<=mid)ans=max(ans,ask(L,R,l,mid)); 73 if(R>mid)ans=max(ans,ask(L,R,mid+1,r)); 74 return ans; 75 } 76 77 int main(){ 78 while(~scanf("%d%d%d",&n,&m,&q)) 79 { 80 mst(g,0),ed=idx=0; 81 F(i,1,n) 82 { 83 f[i]=i,ll[i]=INT_MAX; 84 rr[i]=Rt[i]=is[i]=0; 85 scanf("%d",r+i),G[i].clear(); 86 r[i]=__builtin_ctz(r[i]); 87 } 88 F(i,1,m) 89 { 90 scanf("%d%d%d",&a,&b,&c); 91 if(a==1)adg(b,c),adg(c,b); 92 else f[find(b)]=find(c); 93 } 94 95 F(i,1,n)for(int j=g[i];j;j=nxt[j]) 96 G[find(i)].push_back(Node(find(v[j]),i,r[i]-r[v[j]])); 97 F(i,1,n)if(find(i)==i&&!Rt[i])dfs(i,0,0,i); 98 build(),printf("Case #%d:\n",++cas); 99 while(q--) 100 { 101 scanf("%d%d%d",&a,&b,&c); 102 c=__builtin_ctz(c); 103 if(a==1) 104 { 105 int now=c-r[b]; 106 if(is[b])update(in[find(b)],out[find(b)],-now); 107 if(ll[b]<=rr[b])update(ll[b],rr[b],now); 108 r[b]=c; 109 }else 110 { 111 b=find(b); 112 int ans=c+ask(in[Rt[b]],out[Rt[b]])-ask(in[b],in[b]); 113 printf("%.3f\n",1.0*ans*log(2)); 114 } 115 } 116 } 117 return 0; 118 }