[校内训练20_05_30]ABC

1.一棵树,边权为1,每次给两个点a,b,d1,d2,找到任意一个到a距离为d1,到b距离为d2的点。

大力分类讨论即可。

  1 #include
  2 using namespace std;
  3 const int maxn=1E6+5;
  4 int n,q;
  5 int TI,dfn[maxn],low[maxn],back[maxn],maxd[maxn];
  6 int minn[maxn*4],maxx[maxn*4];
  7 int ans[maxn];
  8 inline int read()
  9 {
 10     char ch=getchar();
 11     while(!isdigit(ch))ch=getchar();
 12     int s=ch-'0';ch=getchar();
 13     while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
 14     return s;
 15 }
 16 int G[55];
 17 inline void write(int x)
 18 {
 19     if(x<0)putchar('-'),x=-x;
 20     int g=0;
 21     do{G[++g]=x%10;x/=10;}while(x);
 22     for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
 23 }
 24 int size,head[maxn];
 25 int dep[maxn],fa[maxn][21];
 26 struct edge
 27 {
 28     int to,next;
 29 }E[maxn*2];
 30 inline void add(int u,int v)
 31 {
 32     E[++size].to=v;
 33     E[size].next=head[u];
 34     head[u]=size;
 35 }
 36 void dfs(int u,int F,int d)
 37 {
 38     low[u]=dfn[u]=++TI;
 39     back[TI]=u;
 40     dep[u]=d;
 41     fa[u][0]=F;
 42     for(int i=1;i<21;++i)
 43         fa[u][i]=fa[fa[u][i-1]][i-1];
 44     for(int i=head[u];i;i=E[i].next)
 45     {
 46         int v=E[i].to;
 47         if(v==F)
 48             continue;
 49         dfs(v,u,d+1);
 50         low[u]=low[v];
 51         maxd[u]=max(maxd[u],maxd[v]+1);
 52     }
 53 }
 54 inline int lca(int x,int y)
 55 {
 56     if(dep[x]<dep[y])
 57         swap(x,y);
 58     int d=dep[x]-dep[y];
 59     for(int i=0;i<21;++i)
 60         if(d&(1<<i))
 61             x=fa[x][i];
 62     if(x==y)
 63         return x;
 64     for(int i=20;i>=0;--i)
 65         if(fa[x][i]!=fa[y][i])
 66             x=fa[x][i],y=fa[y][i];
 67     return fa[x][0];
 68 }
 69 inline int jump(int x,int d)
 70 {
 71     for(int i=0;i<21;++i)
 72         if(d&(1<<i))
 73             x=fa[x][i];
 74     return x;
 75 }
 76 inline int dis(int x,int y)
 77 {
 78     return dep[x]+dep[y]-2*dep[lca(x,y)];
 79 }
 80 void build(int l,int r,int num)
 81 {
 82     if(l==r)
 83     {
 84         minn[num]=maxx[num]=dep[back[l]];
 85         return;
 86     }
 87     int mid=(l+r)>>1;
 88     build(l,mid,num<<1),build(mid+1,r,num<<1|1);
 89     minn[num]=min(minn[num<<1],minn[num<<1|1]);
 90     maxx[num]=max(maxx[num<<1],maxx[num<<1|1]);
 91 }
 92 void ask(int L,int R,int l,int r,int x,int num,int&ans)
 93 {
 94     if(rR)
 95         return;
 96     if(ans!=-1)
 97         return;
 98     int mid=(l+r)>>1;
 99     if(xx)
100         return;
101     if(L<=l&&r<=R)
102     {
103         if(l==r)
104         {
105             ans=back[l];
106             return;
107         }
108         if(minn[num<<1]<=x&&x<=maxx[num<<1])
109             ask(L,R,l,mid,x,num<<1,ans);
110         else if(minn[num<<1|1]<=x&&x<=maxx[num<<1|1])
111             ask(L,R,mid+1,r,x,num<<1|1,ans);
112     }
113     else
114     {
115         ask(L,R,l,mid,x,num<<1,ans);
116         ask(L,R,mid+1,r,x,num<<1|1,ans);
117     }
118 }
119 inline int get(int u,int d)
120 {
121     int ans=-1;
122     ask(dfn[u],low[u],1,n,dep[u]+d,1,ans);
123     return ans;
124 }
125 struct query
126 {
127     int d,id;
128 };
129 vectorQ[maxn];
130 void dfs2(int u,int F,int pos,int P,int p)
131 {
132     if(u!=1)
133     {
134         int len=dep[u]-dep[pos];
135         int g=jump(u,len-1);
136         for(int i=0;ii)
137         {
138             int d=Q[u][i].d,id=Q[u][i].id;
139             if(d<=len)
140                 ans[id]=jump(u,d);
141             else if(P!=0)
142             {
143                 ask(dfn[P],low[P],1,n,dep[pos]+d-len,1,ans[id]);
144             }
145         }
146     }
147     int pos1=0,pos2=0,d1=0,d2=0;
148     for(int i=head[u];i;i=E[i].next)
149     {
150         int v=E[i].to;
151         if(v==F)
152             continue;
153         int d=1+maxd[v];
154         if(d>d1)
155         {
156             d2=d1,pos2=pos1;
157             d1=d,pos1=v;
158         }
159         else if(d>d2)
160             d2=d,pos2=v;
161     }
162     int d3=dep[u]-dep[pos]+p;
163     for(int i=head[u];i;i=E[i].next)
164     {
165         int v=E[i].to;
166         if(v==F)
167             continue;
168         if(pos1==v)
169         {
170             if(d3>=d2)
171                 dfs2(v,u,pos,P,p);
172             else
173                 dfs2(v,u,u,pos2,d2);
174         }
175         else
176         {
177             if(d3>=d1)
178                 dfs2(v,u,pos,P,p);
179             else
180                 dfs2(v,u,u,pos1,d1);
181         }
182     }
183 }
184 inline void solveUp()
185 {
186     int pos1=0,pos2=0,d1=0,d2=0;
187     for(int i=head[1];i;i=E[i].next)
188     {
189         int v=E[i].to;
190         int d=1+maxd[v];
191         if(d>d1)
192         {
193             d2=d1,pos2=pos1;
194             d1=d,pos1=v;
195         }
196         else if(d>d2)
197             d2=d,pos2=v;
198     }
199     for(int i=head[1];i;i=E[i].next)
200     {
201         int v=E[i].to;
202         if(v==pos1)
203             dfs2(v,1,1,pos2,d2);
204         else
205             dfs2(v,1,1,pos1,d1);
206     }
207 }
208 int main()
209 {
210     freopen("hunting.in","r",stdin);
211     freopen("hunting.out","w",stdout);
212     ios::sync_with_stdio(false);
213     n=read(),q=read();
214     for(int i=2;i<=n;++i)
215     {
216         int x=read(),y=read();
217         add(x,y);
218         add(y,x);
219     }
220     dfs(1,1,0);
221     build(1,n,1);
222     for(int i=1;i<=q;++i)
223     {
224         ans[i]=-1;
225         int u=read(),d1=read(),v=read(),d2=read();
226         int w=lca(u,v);
227         int d=dep[u]+dep[v]-2*dep[w];
228         int x=d1-d2+d;
229         if(d1+d20||(x&1)||x>d*2)
230             continue;
231         x/=2;
232         int up=dep[u]-dep[w];
233         if(u==v)
234         {
235             if(d1!=d2)
236                 continue;
237             if(d1==0)
238             {
239                 ans[i]=u;
240                 continue;
241             }
242             ask(dfn[u],low[u],1,n,dep[u]+d1,1,ans[i]);
243             if(u!=1)
244                 Q[u].push_back((query){d1,i});
245         }
246         else if(x==0)
247         {
248             if(d1==0)
249             {
250                 ans[i]=u;
251                 continue;
252             }
253             if(dfn[v]<=dfn[u]&&low[u]<=low[v])
254                 ask(dfn[u],low[u],1,n,dep[u]+d1,1,ans[i]);
255             else if(dfn[u]<=dfn[v]&&low[v]<=low[u])
256             {
257                 int g=jump(v,dep[v]-dep[u]-1);
258                 ask(dfn[u],dfn[g]-1,1,n,dep[u]+d1,1,ans[i]);
259                 ask(low[g]+1,low[u],1,n,dep[u]+d1,1,ans[i]);
260                 if(u!=1&&dfn[u]<=dfn[v]&&low[v]<=low[u])
261                     Q[u].push_back((query){d1,i});
262             }
263             else
264                 ask(dfn[u],low[u],1,n,dep[u]+d1,1,ans[i]);
265         }
266         else if(x==d)
267         {
268             if(d2==0)
269             {
270                 ans[i]=v;
271                 continue;
272             }
273             if(dfn[u]<=dfn[v]&&low[v]<=low[u])
274                 ask(dfn[v],low[v],1,n,dep[v]+d2,1,ans[i]);
275             else if(dfn[v]<=dfn[u]&&low[u]<=low[v])
276             {
277                 int g=jump(u,dep[u]-dep[v]-1);
278                 ask(dfn[v],dfn[g]-1,1,n,dep[v]+d2,1,ans[i]);
279                 ask(low[g]+1,low[v],1,n,dep[v]+d2,1,ans[i]);
280                 if(v!=1&&dfn[v]<=dfn[u]&&low[u]<=low[v])
281                     Q[v].push_back((query){d2,i});
282             }
283             else
284                 ask(dfn[v],low[v],1,n,dep[v]+d2,1,ans[i]);
285         }
286         else if(x==up)
287         {
288             int g1=jump(u,dep[u]-dep[w]-1);
289             int g2=jump(v,dep[v]-dep[w]-1);
290             int l1=dfn[g1],r1=low[g1];
291             int l2=dfn[g2],r2=low[g2];
292             if(l1>l2)
293                 swap(l1,l2),swap(r1,r2);
294             if(w==u)
295             {
296                 ask(dfn[w],dfn[g2]-1,1,n,dep[w]+d1-x,1,ans[i]);
297                 ask(low[g2]+1,low[w],1,n,dep[w]+d1-x,1,ans[i]);
298             }
299             else if(w==v)
300             {
301                 ask(dfn[w],dfn[g1]-1,1,n,dep[w]+d1-x,1,ans[i]);
302                 ask(low[g1]+1,low[w],1,n,dep[w]+d1-x,1,ans[i]);
303             }
304             else
305             {
306                 ask(dfn[w],l1-1,1,n,dep[w]+d1-x,1,ans[i]);
307                 ask(r1+1,l2-1,1,n,dep[w]+d1-x,1,ans[i]);
308                 ask(r2+1,low[w],1,n,dep[w]+d1-x,1,ans[i]);
309             }
310             if(w!=1)
311                 Q[w].push_back((query){d1-x,i});
312         }
313         else if(x<up)
314         {
315             int g=jump(u,x-1);
316             int now=fa[g][0];
317             ask(dfn[now],dfn[g]-1,1,n,dep[now]+d1-x,1,ans[i]);
318             ask(low[g]+1,low[now],1,n,dep[now]+d1-x,1,ans[i]);
319         }
320         else
321         {
322             x=d-x;
323             int g=jump(v,x-1);
324             int now=fa[g][0];
325             ask(dfn[now],dfn[g]-1,1,n,dep[now]+d2-x,1,ans[i]);
326             ask(low[g]+1,low[now],1,n,dep[now]+d2-x,1,ans[i]);
327         }
328     }
329     solveUp();
330     for(int i=1;i<=q;++i)
331         write(ans[i]);
332     return 0;
333 }
334 /*
335 11 1
336 1 2
337 2 3
338 1 4
339 4 5
340 4 6
341 5 7
342 5 8
343 6 9
344 9 10
345 10 11
346 
347 */
View Code

2.

有一张 个点, 条边的无向图,你想选出一个非空点集,使得仅保留这个点集中的点和两个端点都在这个点集里的边后得到的图是连通的。问合法的点集数对2取模。n<=50,一条边两个点的编号差小于等于14。

对于一个非空点集,我们计算2的联通块次方。可以发现,若联通块个数大于等于2那么对4取模就是0。

那么相当于给每一个联通块进行染色,统计总方案数,若对4取模为2,答案为1,否则为0。


3.问一个字符串中所有长度为m的字符串,有多少个长度为m的字符串和它相似。相似定义为两个字符串至多有1个位置上的字符不同。

相似可以变为最长公共前缀+最长公共后缀>=m-1。这相当于给出两个树,问对于一个点u,有多少个点使得dep1[lca(u,v)]+dep2[lca(u,v)]>=m-1。

树上启发式合并即可。我想不会有人能看懂,就不说了。

 

你可能感兴趣的:([校内训练20_05_30]ABC)