Codeforces Round #425 (Div. 2)
B 恶心模拟,读不懂题就GG
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second typedef long long ll; const int N = 200005; int n, len; char s[N], s1[N]; bool vis[27]; void solve() { int len1=strlen(s1), ca, i, j; bool flag=0, flag1=0; for(ca=0,i=0; ca<len; ++i,++ca) { if(s[ca]==s1[i]) continue; else if(s[ca]=='?') { if(vis[s1[i]-'a']==0) { flag=1; break; } } else if(s[ca]=='*') { flag1=1; break; } else { flag=1; break; } } for(ca=len-1,j=len1-1; ca>=0; --j,--ca) { if(s[ca]==s1[j]) continue; else if(s[ca]=='?') { if(vis[s1[j]-'a']==0) { flag=1; break; } } else if(s[ca]=='*') { flag1=1; break; } else { flag=1; break; } } for(int k=i; k<=j; ++k) if(vis[s1[k]-'a']==1) { flag=1; break; } if(len > len1+1 || (flag1==0 && len<len1)) flag=1; if(flag==1) puts("NO"); else puts("YES"); } int main() { scanf("%s", s); for(int i=0; s[i]; ++i) vis[s[i]-'a']=1; scanf("%s %d", s, &n); len = strlen(s); rep(i,1,n) { scanf("%s", s1); solve(); } return 0; }
D lca
题意:一棵树,q个询问,每次问三个点,一个人会从其中一个点到另一个点,第二个人会从另外一个点到前两个点中的一个,问他们路径中重叠的点最多会有多少个。
tags:求出lca,再求出两两之间的距离,最后答案就是 最长的 + 第二长的 - 最短的。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second typedef long long ll; const int N = 200005; int head[N], tot; struct Edge { int to, next; } e[N]; void Addedge(int u, int v) { e[tot]={v, head[u] }, head[u]=tot++; e[tot]={u, head[v] }, head[v]=tot++; } int dep[N], p[N][30]; void dfslca(int u, int fa) { dep[u]=dep[fa]+1, p[u][0]=fa; for(int i=head[u]; i!=-1; i=e[i].next) if(e[i].to!=fa) dfslca(e[i].to, u); } void InitLca(int mn) { memset(p, -1, sizeof(p)); memset(dep, 0, sizeof(dep)); dep[0]=-1; dfslca(1, 0); for(int j=1; (1<<j)<=mn; ++j) for(int i=1; i<=mn; ++i) if(p[i][j-1]!=-1) p[i][j]=p[p[i][j-1]][j-1]; } int Lca(int a, int b) { int i, j; if(dep[a]<dep[b]) swap(a, b); for(i=0; (1<<i)<=dep[a]; ++i); --i; for(j=i; j>=0; --j) if(dep[a]-(1<<j) >= dep[b]) a=p[a][j]; if(a==b) return a; for(j=i; j>=0; --j) if(p[a][j]!=-1 && p[a][j]!=p[b][j]) a=p[a][j], b=p[b][j]; return p[a][0]; } int Dis(int a, int b) { int fab=Lca(a, b); return dep[a]-dep[fab]+dep[b]-dep[fab]; } int main() { mes(head, -1); int n, q, ai; scanf("%d %d", &n, &q); rep(i,2,n) { scanf("%d", &ai); Addedge(ai, i); } InitLca(n); int a, b, c; rep(i,1,q) { scanf("%d %d %d", &a, &b, &c); int d[3]; d[0]=Dis(a, b), d[1]=Dis(b, c), d[2]=Dis(a, c); sort(d, d+3); printf("%d ", (d[2]+d[1]-d[0])/2+1); } return 0; }