激!QTREE系列
我现在才开始刷 QTREE 是不是太弱了?算了不管他……
QTREE: 树链剖分裸题(据说 lct 会超时……该说是真不愧有 spoj 的气息吗?)
1 #include <cstdio> 2 #include <cstring> 3 const int sizeOfPoint=10001; 4 const int sizeOfEdge=20002; 5 const int sizeOfNode=40004; 6 7 inline void swap(int & , int & ); 8 inline int max(int, int); 9 inline char getch(); 10 inline int getint(); 11 inline void putint(int); 12 13 struct edge {int index, point, dist; edge * next;}; 14 edge memory_edge[sizeOfEdge], * port_edge=memory_edge; 15 inline edge * newedge(int, int, int, edge * ); 16 inline void link(int, int, int, int); 17 18 struct node {int c; node * l, * r;}; 19 node memory_node[sizeOfNode], * port_node=memory_node; 20 inline node * newnode(); 21 node * build(int, int); 22 void update(node * , int, int, int, int); 23 int query(node * , int, int, int, int); 24 25 edge * e[sizeOfPoint]; 26 int d[sizeOfPoint], f[sizeOfPoint], s[sizeOfPoint]; 27 int num, idx[sizeOfPoint], son[sizeOfPoint], top[sizeOfPoint]; 28 void dfs(int); 29 void divide(int, int); 30 inline int query(int, int); 31 32 int c, n; 33 int a[sizeOfPoint], k[sizeOfPoint]; 34 node * t; 35 inline void clear(); 36 37 int main() 38 { 39 for (c=getint();c;c--) 40 { 41 clear(); 42 43 n=getint(); 44 for (int i=1;i<n;i++) 45 { 46 int u=getint(), v=getint(), d=getint(); 47 link(i, u, v, d); 48 } 49 dfs(1); 50 divide(1, 1); 51 52 t=build(1, n); 53 for (int i=1;i<=n;i++) 54 update(t, 1, n, idx[i], a[i]); 55 56 while (true) 57 { 58 char ch=getch(); 59 if (ch=='D') break; 60 else if (ch=='Q') 61 { 62 int u=getint(), v=getint(); 63 putint(query(u, v)); 64 } 65 else if (ch=='C') 66 { 67 int u=getint(), v=getint(); 68 a[k[u]]=v; 69 update(t, 1, n, idx[k[u]], v); 70 } 71 } 72 } 73 74 return 0; 75 } 76 77 inline void swap(int & x, int & y) 78 { 79 int t=x; x=y; y=t; 80 } 81 inline int max(int x, int y) 82 { 83 return x>y?x:y; 84 } 85 inline char getch() 86 { 87 register char ch; 88 do ch=getchar(); while (ch!='Q' && ch!='C' && ch!='D'); 89 return ch; 90 } 91 inline int getint() 92 { 93 register int num=0; 94 register char ch=0, last; 95 do last=ch, ch=getchar(); while (ch<'0' || ch>'9'); 96 do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9'); 97 if (last=='-') num=-num; 98 return num; 99 } 100 inline void putint(int num) 101 { 102 char stack[11]; 103 register int top=0; 104 if (num<0) putchar('-'), num=-num; 105 if (num==0) stack[top=1]='0'; 106 for ( ;num;num/=10) stack[++top]=num%10+'0'; 107 for ( ;top;top--) putchar(stack[top]); 108 putchar('\n'); 109 } 110 111 inline edge * newedge(int index, int point, int dist, edge * next) 112 { 113 edge * ret=port_edge++; 114 ret->index=index; ret->point=point; ret->dist=dist; ret->next=next; 115 return ret; 116 } 117 inline void link(int i, int u, int v, int d) 118 { 119 e[u]=newedge(i, v, d, e[u]); 120 e[v]=newedge(i, u, d, e[v]); 121 } 122 123 inline node * newnode() 124 { 125 node * ret=port_node++; 126 ret->c=0; ret->l=NULL; ret->r=NULL; 127 return ret; 128 } 129 node * build(int l, int r) 130 { 131 node * t=newnode(); 132 133 if (l==r) 134 return t; 135 136 int m=(l+r)>>1; 137 t->l=build(l, m); 138 t->r=build(m+1, r); 139 t->c=max(t->l->c, t->r->c); 140 141 return t; 142 } 143 void update(node * t, int l, int r, int k, int v) 144 { 145 if (l==r) 146 { 147 t->c=v; 148 return ; 149 } 150 151 int m=(l+r)>>1; 152 if (k<=m) update(t->l, l, m, k, v); 153 else update(t->r, m+1, r, k, v); 154 t->c=max(t->l->c, t->r->c); 155 } 156 int query(node * t, int l, int r, int ql, int qr) 157 { 158 if (l==ql && r==qr) 159 return t->c; 160 161 int m=(l+r)>>1; 162 if (qr<=m) return query(t->l, l, m, ql, qr); 163 else if (ql>m) return query(t->r, m+1, r, ql, qr); 164 else return max(query(t->l, l, m, ql, m), query(t->r, m+1, r, m+1, qr)); 165 } 166 167 void dfs(int u) 168 { 169 s[u]=1; 170 for (edge * i=e[u];i;i=i->next) if (f[i->point]==-1) 171 { 172 a[i->point]=i->dist; k[i->index]=i->point; 173 f[i->point]=u; d[i->point]=d[u]+1; 174 dfs(i->point); 175 if (s[i->point]>s[son[u]]) 176 son[u]=i->point; 177 } 178 } 179 void divide(int u, int top_u) 180 { 181 idx[u]=++num; top[u]=top_u; 182 if (son[u]) divide(son[u], top_u); 183 for (edge * i=e[u];i;i=i->next) if (!idx[i->point]) 184 divide(i->point, i->point); 185 } 186 inline int query(int u, int v) 187 { 188 int ret=0; 189 190 while (top[u]!=top[v]) 191 { 192 if (d[top[u]]<d[top[v]]) swap(u, v); 193 ret=max(ret, query(t, 1, n, idx[top[u]], idx[u])); 194 u=f[top[u]]; 195 } 196 if (u==v) return ret; 197 198 if (d[u]>d[v]) swap(u, v); 199 ret=max(ret, query(t, 1, n, idx[u]+1, idx[v])); 200 201 return ret; 202 } 203 204 inline void clear() 205 { 206 memset(a, 0, sizeof(a)); 207 memset(k, 0, sizeof(k)); 208 port_edge=memory_edge; port_node=memory_node; 209 memset(e, 0, sizeof(e)); 210 memset(s, 0, sizeof(s)); 211 memset(f, 0xFF, sizeof(f)); f[1]=0; 212 memset(d, 0, sizeof(d)); 213 num=0; 214 memset(idx, 0, sizeof(idx)); 215 memset(son, 0, sizeof(son)); 216 memset(top, 0, sizeof(top)); 217 }
QTREE2: 因为没有修改操作,机智地用了倍增,在 spoj 上貌似挺快的……
1 #include <cstdio> 2 #include <cstring> 3 const int sizeOfPoint=10001; 4 const int sizeOfEdge=20002; 5 6 inline void swap(int & , int & ); 7 inline int lg(int); 8 inline int lowbit(int); 9 inline char getch(); 10 inline int getint(); 11 inline void putint(int); 12 13 struct edge {int point, dist; edge * next;}; 14 edge memory[sizeOfEdge], * port=memory; 15 inline edge * newedge(int, int, edge * ); 16 inline void link(int, int, int); 17 18 int c, n; 19 edge * e[sizeOfPoint]; 20 int a[sizeOfPoint], s[sizeOfPoint]; 21 int f[20][sizeOfPoint], d[sizeOfPoint]; 22 inline void clear(); 23 void dfs(int); 24 inline int anc(int, int); 25 inline int lca(int, int); 26 27 int main() 28 { 29 for (c=getint();c;c--) 30 { 31 clear(); 32 33 n=getint(); 34 for (int i=1;i<n;i++) 35 { 36 int u=getint(), v=getint(), d=getint(); 37 link(u, v, d); 38 } 39 dfs(1); 40 41 while (true) 42 { 43 char ch=getch(); 44 if (ch=='O') break; 45 else if (ch=='I') 46 { 47 int u=getint(), v=getint(), l=lca(u, v); 48 49 putint(s[u]+s[v]-(s[l]<<1)); 50 } 51 else 52 { 53 int u=getint(), v=getint(), k=getint(), l=lca(u, v), s=(d[u]-d[l])+(d[v]-d[l])+1; 54 55 if (d[u]-d[l]>=k) 56 putint(anc(u, k-1)); 57 else 58 putint(anc(v, s-k)); 59 } 60 } 61 } 62 63 return 0; 64 } 65 66 inline void swap(int & x, int & y) 67 { 68 int t=x; x=y; y=t; 69 } 70 inline int lg(int x) 71 { 72 return x?31-__builtin_clz(x):0; 73 } 74 inline int lowbit(int x) 75 { 76 return x & -x; 77 } 78 inline char getch() 79 { 80 register char ch; 81 do ch=getchar(); while (ch!='D' && ch!='K'); 82 if (ch=='D') ch=getchar(); 83 return ch; 84 } 85 inline int getint() 86 { 87 register int num=0; 88 register char ch=0, last; 89 do last=ch, ch=getchar(); while (ch<'0' || ch>'9'); 90 do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9'); 91 if (last=='-') num=-num; 92 return num; 93 } 94 inline void putint(int num) 95 { 96 char stack[11]; 97 register int top=0; 98 if (num==0) stack[top=1]='0'; 99 if (num<0) putchar('-'), num=-num; 100 for ( ;num;num/=10) stack[++top]=num%10+'0'; 101 for ( ;top;top--) putchar(stack[top]); 102 putchar('\n'); 103 } 104 105 inline edge * newedge(int point, int dist, edge * next) 106 { 107 edge * ret=port++; 108 ret->point=point; ret->dist=dist; ret->next=next; 109 return ret; 110 } 111 inline void link(int u, int v, int d) 112 { 113 e[u]=newedge(v, d, e[u]); 114 e[v]=newedge(u, d, e[v]); 115 } 116 117 inline void clear() 118 { 119 port=memory; 120 memset(e, 0, sizeof(e)); 121 memset(f, 0, sizeof(f)); 122 memset(d, 0xFF, sizeof(d)); d[1]=0; 123 memset(a, 0, sizeof(a)); 124 memset(s, 0, sizeof(s)); 125 } 126 void dfs(int u) 127 { 128 if (d[u]>1) 129 { 130 int _lim=lg(d[u]); 131 for (int i=1;i<=_lim;i++) 132 f[i][u]=f[i-1][f[i-1][u]]; 133 } 134 135 for (edge * i=e[u];i;i=i->next) if (d[i->point]==-1) 136 { 137 f[0][i->point]=u; 138 d[i->point]=d[u]+1; 139 a[i->point]=i->dist; 140 s[i->point]=s[u]+i->dist; 141 dfs(i->point); 142 } 143 } 144 inline int anc(int u, int s) 145 { 146 for ( ;s;s-=lowbit(s)) 147 u=f[__builtin_ctz(s)][u]; 148 return u; 149 } 150 inline int lca(int u, int v) 151 { 152 if (d[u]<d[v]) swap(u, v); 153 u=anc(u, d[u]-d[v]); 154 if (u==v) return u; 155 156 for (int i=19;i>=0;i--) 157 if (f[i][u]!=f[i][v]) 158 u=f[i][u], 159 v=f[i][v]; 160 161 return f[0][u]; 162 }
QTREE4:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 const int sizeOfPoint=100001; 5 const int sizeOfEdge=200002; 6 const int sizeOfSeg=2000002; 7 8 inline int lg(int); 9 inline int rev(int); 10 inline int getint(); 11 inline void putint(int); 12 13 struct edge 14 { 15 int point; 16 edge * next; 17 }; 18 edge memoryOfEdge[sizeOfEdge], * portOfEdge=memoryOfEdge; 19 inline edge * newedge(int, edge * ); 20 inline void link(int, int); 21 22 struct seg 23 { 24 bool b; 25 int f; 26 seg * l, * r; 27 inline seg(); 28 inline void pushdown(); 29 inline void maintain(); 30 }; 31 seg * null=new seg(); 32 seg memoryOfSeg[sizeOfSeg], * portOfSeg=memoryOfSeg; 33 inline void swap(seg *& , seg *& ); 34 seg * newseg(seg * =null); 35 seg * insert(seg * , int, int); 36 inline int query(seg * ); 37 38 int n, m; 39 bool c[sizeOfPoint]; 40 int f[sizeOfPoint]; 41 int sg[sizeOfPoint], s[sizeOfPoint]; 42 int dp[sizeOfPoint]; 43 int tot, ans[sizeOfPoint]; 44 edge * e[sizeOfPoint]; 45 seg * t[sizeOfPoint]; 46 inline void bfs(); 47 48 int main() 49 { 50 n=getint(); m=lg(n); 51 for (int i=1;i<=n;i++) 52 c[i]=getint(); 53 for (int i=1;i<n;i++) 54 { 55 int u=getint(), v=getint(); 56 link(u, v); 57 } 58 bfs(); 59 60 if (!tot) ans[tot++]=-1; 61 std::sort(ans, ans+tot); 62 for (int i=0;i<tot;i++) 63 putint(ans[i]); 64 65 return 0; 66 } 67 68 inline int lg(int x) 69 { 70 return 32-__builtin_clz(x); 71 } 72 inline int rev(int x) 73 { 74 int ret=0; 75 for (int i=0;i<m;i++) 76 { 77 ret=(ret<<1)|(x&1); 78 x>>=1; 79 } 80 return ret; 81 } 82 inline int getint() 83 { 84 register int num=0; 85 register char ch; 86 do ch=getchar(); while (ch<'0' || ch>'9'); 87 do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9'); 88 return num; 89 } 90 inline void putint(int num) 91 { 92 char stack[11]; 93 register int top=0; 94 if (num==0) stack[top=1]='0'; 95 if (num<0) putchar('-'), num=-num; 96 for ( ;num;num/=10) stack[++top]=num%10+'0'; 97 for ( ;top;top--) putchar(stack[top]); 98 putchar('\n'); 99 } 100 101 inline edge * newedge(int point, edge * next) 102 { 103 edge * ret=portOfEdge++; 104 ret->point=point; ret->next=next; 105 return ret; 106 } 107 inline void link(int u, int v) 108 { 109 e[u]=newedge(v, e[u]); 110 e[v]=newedge(u, e[v]); 111 } 112 113 inline seg::seg() 114 { 115 b=false; 116 f=0; 117 l=r=this; 118 } 119 inline void seg::pushdown() 120 { 121 if (f) 122 { 123 if (f&1) 124 { 125 swap(l, r); 126 l->f^=f>>1, r->f^=f>>1; 127 } 128 f=0; 129 } 130 } 131 inline void seg::maintain() 132 { 133 b=l->b&r->b; 134 } 135 inline void swap(seg *& a, seg *& b) 136 { 137 seg * t=a; a=b; b=t; 138 } 139 inline seg * newseg(seg * t) 140 { 141 seg * newt=portOfSeg++; 142 *newt=*t; 143 if (t==null) newt->b=false, newt->f=0; 144 return newt; 145 } 146 seg * insert(seg * t, int k, int d) 147 { 148 t=newseg(t); 149 if (d==0) return t->b=true, t; 150 t->pushdown(); 151 if (k&1) t->r=insert(t->r, k>>1, d-1); 152 else t->l=insert(t->l, k>>1, d-1); 153 t->maintain(); 154 return t; 155 } 156 seg * merge(seg * a, seg * b) 157 { 158 if (a==null || b->b) return b; 159 if (b==null || a->b) return a; 160 a->pushdown(), b->pushdown(); 161 seg * t=newseg(); 162 t->l=merge(a->l, b->l); 163 t->r=merge(a->r, b->r); 164 t->maintain(); 165 return t; 166 } 167 inline int query(seg * t) 168 { 169 int ret=0; 170 for (int i=0;i<m;i++) 171 { 172 t->pushdown(); 173 if (t->l->b) 174 { 175 ret=ret<<1|1; 176 t=t->r; 177 } 178 else 179 { 180 ret=ret<<1; 181 t=t->l; 182 } 183 } 184 return ret; 185 } 186 187 inline void bfs() 188 { 189 static int q[sizeOfPoint]; 190 int l=0, r=0; 191 memset(f, 0xFF, sizeof(f)); f[1]=0; 192 for (q[r++]=1;l<r;l++) 193 { 194 int u=q[l]; 195 for (edge * i=e[u];i;i=i->next) if (f[i->point]==-1) 196 { 197 f[i->point]=u; 198 q[r++]=i->point; 199 } 200 } 201 for (int h=r-1;h>=0;h--) 202 { 203 int u=q[h]; 204 t[u]=newseg(); 205 for (edge * i=e[u];i;i=i->next) if (f[i->point]==u) 206 s[u]^=sg[i->point]; 207 for (edge * i=e[u];i;i=i->next) if (f[i->point]==u) 208 { 209 t[i->point]->f^=rev(s[u]^sg[i->point]); 210 t[u]=merge(t[u], t[i->point]); 211 } 212 if (!c[u]) 213 t[u]=insert(t[u], rev(s[u]), m); 214 sg[u]=query(t[u]); 215 } 216 for (int h=0;h<r;h++) 217 { 218 int u=q[h]; 219 if (!c[u] && dp[u]==s[u]) ans[tot++]=u; 220 for (edge * i=e[u];i;i=i->next) if (f[i->point]==u) 221 dp[i->point]=dp[u]^s[u]^sg[i->point]; 222 } 223 }
1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <queue> 5 typedef std::priority_queue<struct pair, std::vector<struct pair>, std::greater<struct pair> > heap; 6 const int sizeOfPoint=100001; 7 const int sizeOfEdge=200002; 8 const int sizeOfSeg=400004; 9 10 inline int min(int, int); 11 inline int getint(); 12 inline void putint(int); 13 14 struct edge 15 { 16 int point; 17 edge * next; 18 }; 19 edge memoryOfEdge[sizeOfEdge], * portOfEdge=memoryOfEdge; 20 inline edge * newedge(int, edge * ); 21 inline void link(int, int); 22 23 struct pair 24 { 25 int w, u, t; 26 inline pair(int, int, int); 27 }; 28 inline bool operator > (pair, pair); 29 30 struct node 31 { 32 int lmin, rmin, sum; 33 inline node(int=0, int=0, int=0); 34 }; 35 inline node merge(node, node); 36 37 struct seg 38 { 39 node d; 40 seg * l, * r; 41 inline void maintain(); 42 }; 43 seg memoryOfSeg[sizeOfSeg], * portOfSeg=memoryOfSeg; 44 inline seg * newseg(); 45 seg * build(int, int); 46 void update(seg * , int, int, int); 47 node query(seg * , int, int, int, int); 48 49 int n, m; 50 int l[sizeOfPoint], r[sizeOfPoint], b[sizeOfPoint]; 51 bool c[sizeOfPoint]; 52 edge * e[sizeOfPoint]; 53 int d[sizeOfPoint], s[sizeOfPoint], f[sizeOfPoint]; 54 int tmp, idx[sizeOfPoint], son[sizeOfPoint], top[sizeOfPoint]; 55 heap h[sizeOfPoint]; 56 int w[sizeOfPoint]; 57 inline void dfs(); 58 inline void getw(int); 59 60 int main() 61 { 62 n=getint(); 63 for (int i=1;i<=n;i++) 64 { 65 int u=getint(), v=getint(); 66 link(u, v); 67 } 68 dfs(); 69 70 return 0; 71 } 72 73 inline int min(int x, int y) 74 { 75 return x<y?x:y; 76 } 77 inline int getint() 78 { 79 register int num=0; 80 register char ch; 81 do ch=getchar(); while (ch<'0' || ch>'9'); 82 do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9'); 83 return num; 84 } 85 inline void putint(int num) 86 { 87 char stack[11]; 88 register int top=0; 89 if (num==0) stack[top=1]='0'; 90 if (num<0) putchar('-'), num=-num; 91 for ( ;num;num/=10) stack[++top]=num%10+'0'; 92 for ( ;top;top--) putchar(stack[top]); 93 putchar('\n'); 94 } 95 96 inline edge * newedge(int point, edge * next) 97 { 98 edge * ret=portOfEdge++; 99 ret->point=point; ret->next=next; 100 return ret; 101 } 102 inline void link(int u, int v) 103 { 104 e[u]=newedge(v, e[u]); 105 e[v]=newedge(u, e[v]); 106 } 107 108 inline pair::pair(int _w, int _u, int _t) 109 { 110 w=_w; u=_u; t=_t; 111 } 112 inline bool operator > (pair a, pair b) 113 { 114 return a.w>b.w; 115 } 116 117 inline node::node(int _lmin, int _rmin, int _sum) 118 { 119 lmin=_lmin; rmin=_rmin; sum=_sum; 120 } 121 inline node merge(node a, node b) 122 { 123 node c; 124 c.lmin=min(a.lmin, a.sum+1+b.lmin); 125 c.rmin=min(b.rmin, a.rmin+1+b.sum); 126 c.sum=a.sum+1+b.sum; 127 return c; 128 } 129 130 inline void seg::maintain() 131 { 132 d=merge(l->d, r->d); 133 } 134 inline seg * newseg() 135 { 136 return portOfSeg++; 137 } 138 seg * build(int l, int r) 139 { 140 seg * t=newseg(); 141 int m=(l+r)>>1; 142 143 if (l==r) 144 { 145 t->d.lmin=t->d.rmin=w[m]; 146 t->d.sum=0; 147 } 148 else 149 { 150 t->l=build(l, m); 151 t->r=build(m+1, r); 152 t->maintain(); 153 } 154 155 return t; 156 } 157 void update(seg * t, int l, int r, int k) 158 { 159 int m=(l+r)>>1; 160 161 if (l==r) 162 t->d.lmin=t->d.rmin=w[m]; 163 else 164 { 165 if (k<=m) update(t->l, l, m, k); 166 else update(t->r, m+1, r, k); 167 t->maintain(); 168 } 169 } 170 node query(seg * t, int l, int r, int ql, int qr) 171 { 172 if (l==ql && r==qr) return t->d; 173 int m=(l+r)>>1; 174 if (qr<=m) return query(t->l, l, m, ql, qr); 175 else if (ql>m) return query(t->r, m+1, r, ql, qr); 176 else return merge(query(t->l, l, m, ql, m), query(t->r, m+1, r, m+1, qr)); 177 } 178 179 inline void dfs() 180 { 181 static edge * t[sizeOfPoint]; 182 memmove(t, e, sizeof(e)); 183 }