Codeforces Round #425 (Div. 2)

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\n", (d[2]+d[1]-d[0])/2+1);
    }

    return 0;
}

 

posted @ 2017-07-29 09:43  v9fly  阅读(180)  评论(0编辑  收藏  举报