SPOJ 2798 Query on a tree again 树链剖分

这题真是神题!

当然我不是说这题有多神,而是你数组开小了和开大了得分不同,用不同版本的编译器得分不同。。。(数组没有越界的情况下)

呜呜。。。至今没有ac。一直83分。。。抑郁了。。。

跪求神犇指明错误。。。

 

View Code
  1 #include <iostream>

  2 #include <cstring>

  3 #include <cstdlib>

  4 #include <algorithm>

  5 #include <cstdio>

  6 

  7 #define N 151000

  8 #define M 251000

  9 #define INF 1e9

 10 

 11 using namespace std;

 12 

 13 struct RT

 14 {

 15     int mn,zb;

 16 }rt[N<<2];

 17 

 18 int head[N],to[M],next[M];

 19 int tot,n,qu,cnt;

 20 int fa[N],son[N],sz[N],dep[N],top[N],q[N];

 21 int bh[N],anbh[N];

 22 

 23 inline void add(int u,int v)

 24 {

 25     to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++;

 26 }

 27 

 28 inline void init()

 29 {

 30     memset(head,-1,sizeof head); cnt=0;

 31     tot=0;

 32 }

 33 

 34 inline void prep()

 35 {

 36     int h=1,t=2,sta;

 37     q[1]=1; dep[1]=1;

 38     while(h<t)

 39     {

 40         sta=q[h++]; sz[sta]=1;

 41         for(int i=head[sta];~i;i=next[i])

 42             if(to[i]!=fa[sta])

 43             {

 44                 fa[to[i]]=sta;

 45                 dep[to[i]]=dep[sta]+1;

 46                 q[t++]=to[i];

 47             }

 48     }

 49     for(int j=t-1;j>=1;j--)

 50     {

 51         sta=q[j];

 52         for(int i=head[sta];~i;i=next[i])

 53             if(to[i]!=fa[sta])

 54             {

 55                 sz[sta]+=sz[to[i]];

 56                 if(sz[to[i]]>sz[son[sta]]) son[sta]=to[i]; 

 57             }

 58     }

 59     for(int i=1;i<t;i++)

 60     {

 61         sta=q[i];

 62         if(son[fa[sta]]==sta) top[sta]=top[fa[sta]];

 63         else top[sta]=sta;

 64     }

 65 }

 66 

 67 inline void rewrite()

 68 {

 69     for(int i=1;i<=n;i++)

 70         if(top[i]==i)

 71             for(int j=i;j;j=son[j])

 72             {

 73                 bh[j]=++tot;

 74                 anbh[tot]=j;

 75             }

 76 }

 77 

 78 inline void pushup(int u)

 79 {

 80     if(rt[u<<1].mn<rt[u<<1|1].mn) rt[u]=rt[u<<1];

 81     else rt[u]=rt[u<<1|1];

 82 }

 83 

 84 inline void build(int u,int L,int R)

 85 {

 86     if(L==R) {rt[u].mn=INF;rt[u].zb=L;return;}

 87     int MID=(L+R)>>1;

 88     build(u<<1,L,MID); build(u<<1|1,MID+1,R);

 89     pushup(u);

 90 }

 91 

 92 inline void read()

 93 {

 94     init();

 95     scanf("%d%d",&n,&qu);

 96     for(int i=1,a,b;i<n;i++)

 97     {

 98         scanf("%d%d",&a,&b);

 99         add(a,b); add(b,a);

100     }

101     prep();

102     rewrite();

103     build(1,1,tot);

104 }

105 

106 inline int queryval(int u,int L,int R,int pos)

107 {

108     if(L==R) return rt[u].mn;

109     int MID=(L+R)>>1;

110     if(pos<=MID) return queryval(u<<1,L,MID,pos);

111     return queryval(u<<1|1,MID+1,R,pos);

112 }

113 

114 inline void updata(int u,int L,int R,int pos,int val)

115 {

116     if(L==R) {rt[u].mn=val;return;}

117     int MID=(L+R)>>1;

118     if(pos<=MID) updata(u<<1,L,MID,pos,val);

119     else updata(u<<1|1,MID+1,R,pos,val);

120     pushup(u);

121 }

122 

123 inline void change(int x)

124 {

125     int val=queryval(1,1,tot,bh[x]);

126     if(val==INF) updata(1,1,tot,bh[x],dep[x]);

127     else updata(1,1,tot,bh[x],INF);

128 }

129 

130 inline RT querymin(int u,int L,int R,int l,int r)

131 {

132     if(l<=L&&R<=r) return rt[u];

133     int MID=(L+R)>>1; RT lp,rp; lp.mn=rp.mn=INF;

134     if(l<=MID) lp=querymin(u<<1,L,MID,l,r);

135     if(MID<r) rp=querymin(u<<1|1,MID+1,R,l,r);

136     if(lp.mn<rp.mn) return lp;

137     return rp;

138 }

139 

140 inline void query(int x,int y)

141 {

142     RT tmp,res; res.mn=INF;

143     while(top[x]!=top[y])

144     {

145         if(dep[top[x]]<dep[top[y]]) swap(x,y);

146         tmp=querymin(1,1,tot,bh[top[x]],bh[x]);

147         if(tmp.mn<res.mn) res=tmp;

148         x=fa[top[x]];

149     }

150     if(bh[x]>bh[y]) swap(x,y);

151     tmp=querymin(1,1,tot,bh[x],bh[y]);

152     if(tmp.mn<res.mn) res=tmp;

153     if(res.mn!=INF) printf("%d\n",anbh[res.zb]);

154     else puts("-1");

155 }

156 

157 inline void go()

158 {

159     int a,b;

160     while(qu--)

161     {

162         scanf("%d%d",&a,&b);

163         if(a==0) change(b);

164         else query(b,1);

165     }

166 }

167 

168 int main()

169 {

170     read(),go();

171     return 0;

172 }

 

 

你可能感兴趣的:(query)