[BZOJ 3681]Ariettad

终于是打完了 CH 上的数据结构专场了……

不过看样子还有一套 5555

传送门: http://ch.ezoj.tk/contest/CH%20Round%20%2351%20-%20Shinrein%E7%A5%AD%20%231

 

直接连边会 TLE。但是,连出去的点都是一个连续点集……

——于是我们机智的用了 “可合并线段树”(好,) 以空间换取时间

在网络流的图中塞一棵可持久化线段树进去,这样区间连边时就只会连 O(logn) 的边了

智商++,而且这道题让我重新认识了线段树的合并,真是受益匪浅~

不过——

我恨卡内存!!!

 

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <vector>

  4 const int inf=0x7FFFFFFF;

  5 const int sizeOfSegmemt=4000004;

  6 const int sizeOfEdge=2000002;

  7 const int sizeOfPoint=320032;

  8 const int sizeOfNote=10001;

  9 

 10 int n, m;

 11 int P[sizeOfNote], H[sizeOfNote];

 12 std::vector<int> son[sizeOfPoint];

 13 inline int min(int, int);

 14 inline int getint();

 15 inline void putint(int);

 16 

 17 struct seg {int p; seg * l, * r;};

 18 seg memory_seg[sizeOfSegmemt], * port_seg=memory_seg;

 19 seg * t[sizeOfPoint];

 20 inline seg * newseg();

 21 void insert(seg *& , int, int, int, int);

 22 seg * merge(seg * , seg * );

 23 void query(seg * , int, int, int, int, int);

 24 void dfs(int);

 25 

 26 int S, T;

 27 int V, E;

 28 struct edge {int point, flow; edge * next, * pair;};

 29 edge memory_edge[sizeOfEdge], * port_edge=memory_edge;

 30 edge * e[sizeOfPoint];

 31 int h[sizeOfPoint], gap[sizeOfPoint];

 32 inline edge * newedge(int, int, edge * );

 33 inline void link(int, int, int);

 34 int head, tail, queue[sizeOfPoint];

 35 inline bool bfs();

 36 edge * r[sizeOfPoint], * p[sizeOfPoint];

 37 int aug[sizeOfPoint];

 38 inline int isap();

 39 

 40 int main()

 41 {

 42     int D, L, R, M;

 43 

 44     n=getint(), m=getint();

 45     S=0; T=n+1; V=n+1;

 46     for (int i=2;i<=n;i++)

 47     {

 48         P[i]=getint();

 49         son[P[i]].push_back(i);

 50     }

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

 52         H[i]=getint();

 53 

 54     dfs(1);

 55 

 56     for (int i=1;i<=m;i++)

 57     {

 58         L=getint(), R=getint(), D=getint(), M=getint();

 59         link(S, ++V, M);

 60         query(t[D], 1, n, L, R, V);

 61     }

 62 

 63     putint(isap());

 64 

 65     return 0;

 66 }

 67 inline int min(int x, int y)

 68 {

 69     return x<y?x:y;

 70 }

 71 inline int getint()

 72 {

 73     register int num=0;

 74     register char ch;

 75     do ch=getchar(); while (ch<'0' || ch>'9');

 76     do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');

 77     return num;

 78 }

 79 inline void putint(int num)

 80 {

 81     char stack[11];

 82     register int top=0;

 83     if (num==0) stack[top=1]='0';

 84     for ( ;num;num/=10) stack[++top]=num%10+'0';

 85     for ( ;top;top--) putchar(stack[top]);

 86     putchar('\n');

 87 }

 88 inline edge * newedge(int point, int flow, edge * next)

 89 {

 90     edge * ret=port_edge++;

 91     ret->point=point; ret->flow=flow; ret->next=next;

 92     return ret;

 93 }

 94 inline void link(int u, int v, int f)

 95 {

 96     e[u]=newedge(v, f, e[u]); e[v]=newedge(u, 0, e[v]);

 97     e[u]->pair=e[v]; e[v]->pair=e[u];

 98 }

 99 inline bool bfs()

100 {

101     memset(h, 0xFF, sizeof(h)); h[T]=0;

102     head=tail=0;

103     for (queue[tail++]=T;head<tail;head++)

104     {

105         int u=queue[head];

106         gap[h[u]]++;

107         for (edge * i=e[u];i;i=i->next) if (h[i->point]==-1)

108         {

109             h[i->point]=h[u]+1;

110             queue[tail++]=i->point;

111         }

112     }

113     return h[S]>-1;

114 }

115 inline int isap()

116 {

117     int flow=0;

118     int hmin=0;

119 

120     if (!bfs()) return 0;

121 

122     memcpy(r, e, sizeof(e));

123     memset(p, 0, sizeof(p));

124     aug[S]=inf;

125     for (int u=S;h[S]<V; )

126     {

127         if (u==T)

128         {

129             flow+=aug[T];

130             for (edge * i=p[T];i;i=p[i->point])

131                 i->pair->flow-=aug[T], i->flow+=aug[T], aug[i->point]-=aug[T];

132             for (edge * i=p[T];i;i=p[i->point]) if (aug[i->point])

133             {

134                 u=i->point;

135                 break;

136             }

137         }

138 

139         edge *& i=r[u];

140         for ( ;i && (!i->flow || h[i->point]+1!=h[u]);i=i->next);

141         if (i)

142         {

143             p[i->point]=i->pair; aug[i->point]=min(aug[u], i->flow);

144             u=i->point;

145         }

146         else

147         {

148             if (!--gap[h[u]]) break;

149             hmin=V;

150             for (edge * j=e[u];j;j=j->next) if (j->flow && h[j->point]+1<hmin)

151             {

152                 r[u]=j;

153                 hmin=h[j->point]+1;

154             }

155             ++gap[h[u]=hmin];

156             u=u==S?S:p[u]->point;

157         }

158     }

159 

160     return flow;

161 }

162 

163 inline seg * newseg()

164 {

165     seg * ret=port_seg++;

166     ret->p=++V; ret->l=ret->r=NULL;

167     return ret;

168 }

169 void insert(seg *& t, int l, int r, int p, int v)

170 {

171     if (!t) t=newseg();

172     if (l==r) link(t->p, v, inf);

173     else

174     {

175         int m=(l+r)>>1;

176         if (p<=m) insert(t->l, l, m, p, v), link(t->p, t->l->p, inf);

177         else insert(t->r, m+1, r, p, v), link(t->p, t->r->p, inf);

178     }

179 }

180 seg * merge(seg * x, seg * y)

181 {

182     if (!x) return y;

183     if (!y) return x;

184     seg * t=newseg();

185     bool leaf=true;

186     if ((t->l=merge(x->l, y->l))) link(t->p, t->l->p, inf), leaf=false;

187     if ((t->r=merge(x->r, y->r))) link(t->p, t->r->p, inf), leaf=false;

188     if (leaf) link(t->p, x->p, inf), link(t->p, y->p, inf);

189     return t;

190 }

191 void query(seg * t, int l, int r, int ql, int qr, int p)

192 {

193     if (!t) return ;

194     if (l==ql && r==qr) link(p, t->p, inf);

195     else

196     {

197         int m=(l+r)>>1;

198         if (qr<=m) query(t->l, l, m, ql, qr, p);

199         else if (ql>=m+1) query(t->r, m+1, r, ql, qr, p);

200         else query(t->l, l, m, ql, m, p), query(t->r, m+1, r, m+1, qr, p);

201     }

202 }

203 void dfs(int u)

204 {

205     link(u, T, 1);

206     insert(t[u], 1, n, H[u], u);

207     for (unsigned int i=0;i<son[u].size();i++)

208     {

209         dfs(son[u][i]);

210         t[u]=merge(t[u], t[son[u][i]]);

211     }

212 }
我恨卡内存++

 

你可能感兴趣的:(ZOJ)