dyllalala

导航

激!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 }
QTREE

 

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 }
QTREE2

 

 

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

 

  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 }
QTREE5

 

posted on 2014-12-23 20:56  dyllalala  阅读(417)  评论(1编辑  收藏  举报