hdu 6039 Gear Up(dfs序+线段树)

题目链接:hdu 6039 Gear Up

题意:

给出一些齿轮,有些齿轮是边相连,也就是拥有相同的线速度,
有的齿轮是轴相连,也就是拥有相同的角速度,现在给某个齿轮一个速度,
求这些齿轮中的最大速度,同时还有修改操作,可以更改某个齿轮的半径大小

题解:

官方题解:

  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 }
View Code

 

posted @ 2017-07-26 21:32  bin_gege  阅读(287)  评论(0编辑  收藏  举报