终于是打完了 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 }