0-1-Tree CodeForces - 1156D
https://cn.vjudge.net/problem/CodeForces-1156D
解法1:暴力dp,分情况讨论,难
代码参考:https://blog.csdn.net/Coldfresh/article/details/89792170
#include<bits/stdc++.h>
#define RD1(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d %d",&x,&y)
#define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z)
#define RDL1(x) scanf("%lld",&x)
#define RDL2(x,y) scanf("%lld %lld",&x,&y)
#define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)
#define CLR(x) memset(x,0,sizeof(x))
#define max1 (500+10)
#define max2 (1000+10)
#define maxn (1000000+10)
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mod (1000000007)
#define pi acos(-1)
#define eps 1e-14
#define acc ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define INF(x) memset(x,inf,sizeof(x))
#define NEG(x) memset(x,0xff,sizeof(x))
#define CLRQ(Q) while(!(Q).empty())(Q).pop()
#define see(x) (cerr<<(#x)<<'='<<(x)<<' ')
#define NL cout<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n;
int head[maxn],pre[maxn<<1],to[maxn<<1],tot,t[maxn<<1];
void adde(int u,int v,int w){to[++tot]=v,pre[tot]=head[u],head[u]=tot,t[tot]=w;}
ll dp[maxn][4];
//dp[i][0] root i,all 0
//dp[i][1] root i,all 1
//dp[i][2] root i,000...111
//dp[i][3] root i,111...000
ll ans=0;
void dfs(int u,int fa)
{
    for(int i=head[u];i;i=pre[i])
    {
        int v=to[i];if(v==fa)continue;
        dfs(v,u);
        if(t[i]==1)
        {
            ans+=dp[u][1]*(dp[v][1]+1)*2;
            ans+=(dp[u][0]+dp[u][3])*(dp[v][1]+1);
            ans+=dp[u][1]*(dp[v][3]+dp[v][0]);
            
            dp[u][1]+=dp[v][1]+1;
            dp[u][3]+=dp[v][0];
            dp[u][3]+=dp[v][3];
        }
        else
        {
            ans+=dp[u][0]*(dp[v][0]+1)*2;
            ans+=(dp[u][1]+dp[u][2])*(dp[v][0]+1);
            ans+=dp[u][0]*(dp[v][1]+dp[v][2]);
            dp[u][2]+=dp[v][1];
            dp[u][0]+=dp[v][0]+1;
            dp[u][2]+=dp[v][2];
        }
    }
    ans+=(dp[u][0]+dp[u][1])*2+dp[u][2]+dp[u][3];
}
/*
2
1 2 1
*/
int main()
{
    RD1(n);for(int i=1;i<n;i++){int u,v,w;RD3(u,v,w);adde(v,u,w);adde(u,v,w);}
    dfs(1,0);printf("%lld",ans);
    return 0;
}


解法2:并查集,相对简单
精妙的代码实现:
https://blog.csdn.net/qq_41730082/article/details/89742810

A and B and Interesting Substrings CodeForces - 519D
#include<bits/stdc++.h>
#define RD1(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d %d",&x,&y)
#define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z)
#define RDL1(x) scanf("%lld",&x)
#define RDL2(x,y) scanf("%lld %lld",&x,&y)
#define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)
#define CLR(x) memset(x,0,sizeof(x))
#define max1 (500+10)
#define max2 (1000+10)
#define maxn (100000+10)
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mod (1000000007)
#define pi acos(-1)
#define eps 1e-14
#define acc ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define INF(x) memset(x,inf,sizeof(x))
#define NEG(x) memset(x,0xff,sizeof(x))
#define CLRQ(Q) while(!(Q).empty())(Q).pop()
#define see(x) (cerr<<(#x)<<'='<<(x)<<' ')
#define NL cout<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int val[200];
ll sum[maxn];
char s[maxn];
map<ll,int>m[26];
int main()
{
    for(int i='a';i<='z';i++)RD1(val[i]);
    scanf("%s",s);
    ll ans=0;
    m[s[0]-'a'][val[s[0]]]++;
    sum[0]=val[s[0]];
    for(int i=1;s[i];i++)
    {
        char cur=s[i];
        ans+=m[cur-'a'][sum[i-1]];
        sum[i]=sum[i-1]+val[cur];
        m[cur-'a'][sum[i]]++;
    }
    cout<<ans;
    return 0;
}


A and B and Lecture Rooms CodeForces - 519E
lca模板见:https://www.cnblogs.com/zhouzhendong/p/7256007.html
#include<bits/stdc++.h>
#define RD1(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d %d",&x,&y)
#define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z)
#define RDL1(x) scanf("%lld",&x)
#define RDL2(x,y) scanf("%lld %lld",&x,&y)
#define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)
#define CLR(x) memset(x,0,sizeof(x))
#define max1 (500+10)
#define max2 (1000+10)
#define maxn (100000+10)
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mod (1000000007)
#define pi acos(-1)
#define eps 1e-14
#define acc ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define INF(x) memset(x,inf,sizeof(x))
#define NEG(x) memset(x,0xff,sizeof(x))
#define CLRQ(Q) while(!(Q).empty())(Q).pop()
#define see(x) (cerr<<(#x)<<'='<<(x)<<' ')
#define NL cout<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n;
int head[maxn],tot,to[maxn<<1],pre[maxn<<1],dep[maxn],p[maxn],f[maxn][20],sz[maxn];
void adde(int u,int v)
{
    to[++tot]=v,pre[tot]=head[u],head[u]=tot;
}
void dfs(int u)
{
    dep[u]=dep[p[u]]+1;
    sz[u]=1;
    f[u][0]=p[u];
    for(int i=1;i<20;i++)
        f[u][i]=f[f[u][i-1]][i-1];
    
    for(int i=head[u];i;i=pre[i])
    {
        int v=to[i];if(v==p[u])continue;
        p[v]=u;dfs(v);
        sz[u]+=sz[v];
    }
}
int lca(int x,int y)
{
    for(int i=19;i>=0;i--)if(dep[x]-(1<<i)>=dep[y])
        x=f[x][i];
    if(x==y)return x;
    for(int i=19;i>=0;i--)if(f[x][i]!=f[y][i])
        x=f[x][i],y=f[y][i];
    return f[x][0];
}
int query(int x,int y)
{
    if(x==y)return sz[1];
    if(dep[x]<dep[y])swap(x,y);
    int ast=lca(x,y);
    int len=dep[x]-dep[ast]+dep[y]-dep[ast];
    if(len%2)return 0;
    len>>=1;
    bool level=dep[x]==dep[y];
    if(level)
    {
        for(int i=1;i<len;i++)x=p[x],y=p[y];
        return sz[1]-sz[x]-sz[y];
    }
    else
    {
        for(int i=1;i<len;i++)x=p[x];
        return sz[p[x]]-sz[x];
    }
}
int main()
{
    RD1(n);for(int i=1;i<n;i++)
    {
        int u,v;RD2(u,v);adde(u,v),adde(v,u);    
    }
    dfs(1);
    int q;RD1(q);
    while(q--)
    {
        int u,v;RD2(u,v);
        printf("%d\n",query(u,v));
    }
    return 0;
}


1-2-K Game CodeForces - 1194D
https://cn.vjudge.net/problem/CodeForces-1194D
打表找规律
#include<bits/stdc++.h>
#define RD1(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d %d",&x,&y)
#define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z)
#define RDL1(x) scanf("%lld",&x)
#define RDL2(x,y) scanf("%lld %lld",&x,&y)
#define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)
#define CLR(x) memset(x,0,sizeof(x))
#define max1 (500+10)
#define max2 (1000+10)
#define maxn (100000+10)
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mod (1000000007)
#define pi acos(-1)
#define eps 1e-14
#define acc ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define INF(x) memset(x,inf,sizeof(x))
#define NEG(x) memset(x,0xff,sizeof(x))
#define CLRQ(Q) while(!(Q).empty())(Q).pop()
#define see(x) (cerr<<(#x)<<'='<<(x)<<' ')
#define NL cout<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int sg[maxn];
int brute(int n,int k)
{
    CLR(sg);sg[1]=sg[2]=1;
    for(int i=1;i<=n;i++)
    {
        if(!sg[i-1]){sg[i]=1;continue;}
        if(!sg[i-2]){sg[i]=1;continue;}
        if(i-k>=0&&!sg[i-k]){sg[i]=1;continue;}
    }
    for(int i=0;i<=n;i++)see(i),see(sg[i]),NL;
    NL;
}
int main()
{
    //brute(100,10);
    int ttt;RD1(ttt);while(ttt--)
    {
        int n,k;RD2(n,k);
        if(n==k)printf("Alice\n");
        else if(k%3)
        {
            if(n%3)printf("Alice\n");
            else printf("Bob\n");    
        }
        else
        {
            n%=(k+1);
            if(n==k)printf("Alice\n");
            else if(n%3)printf("Alice\n");
            else printf("Bob\n");
        }
    }
    return 0;
}


"Or" Game CodeForces - 579D
https://cn.vjudge.net/problem/CodeForces-579D

暴力正解:https://www.cnblogs.com/zhangchengc919/p/5572966.html
想到了就很简单


Prefixes and Suffixes CodeForces - 432D
https://cn.vjudge.net/problem/CodeForces-432D
kmp+dp的思路不好想,
一般的dp是以当前状态为目标态,用多个之前的状态依次更新
而这里用当前态直接更新'未来'状态
还有一种冷门的z算法,反正自己是想不到这么做的
思路见https://blog.csdn.net/weixin_44031744/article/details/86693545
代码虽短,理解不易
#include<bits/stdc++.h>
#define RD1(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d %d",&x,&y)
#define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z)
#define RDL1(x) scanf("%lld",&x)
#define RDL2(x,y) scanf("%lld %lld",&x,&y)
#define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)
#define CLR(x) memset(x,0,sizeof(x))
#define max1 (500+10)
#define max2 (1000+10)
#define maxn (100000+10)
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mod (1000000007)
#define pi acos(-1)
#define eps 1e-14
#define acc ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define INF(x) memset(x,inf,sizeof(x))
#define NEG(x) memset(x,0xff,sizeof(x))
#define CLRQ(Q) while(!(Q).empty())(Q).pop()
#define see(x) (cerr<<(#x)<<'='<<(x)<<' ')
#define NL cout<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int pre[maxn];
//pre[i]:the end pos of the max prefix,equals the suffix ,of the substring[1,i];
char s[maxn];
int rec[maxn],pr;
int dp[maxn];
void getpre(int len)
{
    int fail=pre[0]=-1,pos=0;
    while(pos<len)
    {
        //see(pos),see(pre[pos]),NL;
        while(fail!=-1&&s[fail]!=s[pos]) fail=pre[fail];
        pre[++pos]=++fail;
    }
}
int main()
{
    scanf("%s",s);int len=strlen(s);getpre(len);
    int pt=len;
    while(pt)
        rec[pr++]=pt,pt=pre[pt];
    for(int i=len;i>=0;i--)dp[i]=1;
    for(int i=len;i;i--)
    {
    //    see(i),see(pre[i]),see(dp[i]),see(dp[pre[i]]),NL;
        dp[pre[i]]+=dp[i];
    }
    printf("%d\n",pr);
    while(pr--)
        printf("%d %d\n",rec[pr],dp[rec[pr]]);
    return 0;
}



Peculiar apple-tree CodeForces - 931D
https://cn.vjudge.net/problem/CodeForces-931D
求出每个深度有多少个节点并mod2,最后求和,得到答案
#include<bits/stdc++.h>
#define RD1(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d %d",&x,&y)
#define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z)
#define RDL1(x) scanf("%lld",&x)
#define RDL2(x,y) scanf("%lld %lld",&x,&y)
#define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)
#define CLR(x) memset(x,0,sizeof(x))
#define max1 (500+10)
#define max2 (1000+10)
#define maxn (100000+10)
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mod (1000000007)
#define pi acos(-1)
#define eps 1e-14
#define acc ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define INF(x) memset(x,inf,sizeof(x))
#define NEG(x) memset(x,0xff,sizeof(x))
#define CLRQ(Q) while(!(Q).empty())(Q).pop()
#define see(x) (cerr<<(#x)<<'='<<(x)<<' ')
#define NL cout<<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int head[maxn],to[maxn<<1],pre[maxn<<1],tot,dep[maxn];
int n;
void adde(int u,int v)
{
    to[++tot]=v,pre[tot]=head[u],head[u]=tot;
}
void dfs(int u,int f,int d)
{
    dep[d]++;
    for(int i=head[u];i;i=pre[i])
    {
        int v=to[i];if(v==f)continue;
        dfs(v,u,d+1);
    }
}
int main()
{
    RD1(n);for(int i=2;i<=n;i++)
    {
        int u;RD1(u);adde(i,u),adde(u,i); 
    }
    int ans=0;
    dfs(1,0,0);for(int i=0;i<=n;i++)ans+=dep[i]&1;
    cout<<ans;
    return 0;
}

Minimum Diameter Tree

https://cn.vjudge.net/problem/CodeForces-1087D
思维题,一旦想到就很简单
直径必经过两个叶子节点,中间路径上的边全部置0,将s均摊在所有叶子结点上就行了