zoukankan      html  css  js  c++  java
  • BZOJ 10.29--11.7刷题总结

    在总结之前,预祝2018级信奥队明天NOIP RP++

    @JZYshuraK @ysy20021208 @jiangminghong @EM_LGH @zcs0724  以及我自己

    开始总结题目

    BZOJ1977 [BeiJing2010组队]次小生成树 Tree

    BZOJ 1977[BeiJing2010组队]次小生成树 Tree

    这道题我们用Kruskal把这棵最小生成树构建出来,之后我们枚举每一条非树边,也需要快速求出每一条树链上的最小边与次小边。

    这个东西我们可以用倍增LCA来求。

    D[x][i]=max(D[x][i-1],D[f[x][i-1]][i-1]);

    D2[x][i]=max(D2[x][i-1],D2[f[x][i-1]][i-1]);

    D2[x][i]=min(D[x][i-1],D[f[x][i-1]][i-1]);
    D2[x][i]=max(D2[x][i],D2[x][i-1]);
    D2[x][i]=max(D2[x][i],D2[f[x][i-1]][i-1]);

    这几步就是求最长链与次长链。

    之后就没了。

    #include<cstdio>
    #include<algorithm>
    #define N 300010
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    int dep[N];
    int f[N][20];
    int head[N];
    int to[N];
    int nex[N];
    int fa[N];
    int val[N];
    int idx;
    int n,m;
    int D[N][20];
    int D2[N][20];
    int size[N];
    long long ans;
    int minn=0x3f3f3f3f;
    struct tree
    {
        int x,y,z,is;
    }a[N];
    bool cmp(const tree &a,const tree &b){return a.z<b.z;}
    void addedge(int a,int b,int c)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
        val[idx]=c;
    }
    int find(int x)
    {
        if(fa[x]!=x)
            fa[x]=find(fa[x]);
        return fa[x];
    }
    void dfs(int x)
    {
        for(int i=1;i<=17;i++)
        {
            if(dep[x]<(1<<i))
                break;
            f[x][i]=f[f[x][i-1]][i-1];
            D[x][i]=max(D[x][i-1],D[f[x][i-1]][i-1]);
            if(D[x][i-1]==D[f[x][i-1]][i-1])
                D2[x][i]=max(D2[x][i-1],D2[f[x][i-1]][i-1]);
            else
            {
                D2[x][i]=min(D[x][i-1],D[f[x][i-1]][i-1]);
                D2[x][i]=max(D2[x][i],D2[x][i-1]);
                D2[x][i]=max(D2[x][i],D2[f[x][i-1]][i-1]);
            }
        }
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=f[x][0])
            {
                dep[to[i]]=dep[x]+1;
                D[to[i]][0]=val[i];
                f[to[i]][0]=x;
                dfs(to[i]);
            }
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])
            swap(x,y);
        int deep=dep[x]-dep[y];
        for(int i=17;i>=0;i--)
            if(deep&(1<<i))
                x=f[x][i];
        for(int i=17;i>=0;i--)
        {
            if(f[x][i]!=f[y][i])
                x=f[x][i],y=f[y][i];
        }
        if(x==y)
            return x;
        return f[x][0];
    }
    void merge(int x,int y)
    {
        if(size[x]>size[y])
        {
            fa[y]=x;
            size[x]+=size[y];
        }
        else
        {
            fa[x]=y;
            size[y]+=size[x];    
        }
    }
    void go(int x,int fa,int cost)
    {
        int max1=0,max2=0;
        int deep=dep[x]-dep[fa];
        for(int i=0;i<=17;i++)
        {
            if(deep&(1<<i))
            {
                if(D[x][i]>max1)
                {
                    max2=max1;
                    max1=D[x][i];
                }
                max2=max(max2,D2[x][i]);
                x=f[x][i];
            }
        }
        if(max1!=cost)
            minn=min(minn,cost-max1);
        else
            minn=min(minn,cost-max2);
    }
    void solve(int j,int cost)
    {
        int x=a[j].x;
        int y=a[j].y;
        int fa=lca(x,y);
        go(x,fa,cost);
        go(y,fa,cost);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            fa[i]=i;
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
        sort(a+1,a+m+1,cmp);
        int tot=0;
        for(int i=1;i<=m;i++)
        {
            int fx=find(a[i].x);
            int fy=find(a[i].y);
            if(fx!=fy)
            {
                tot++;
                a[i].is=1;
                ans+=a[i].z;
                merge(fx,fy);
                addedge(a[i].x,a[i].y,a[i].z);
                addedge(a[i].y,a[i].x,a[i].z);
                if(tot==n-1)
                    break;
            }
        }
        dfs(1);
        for(int i=1;i<=m;i++)
            if(!a[i].is)
                solve(i,a[i].z);
        printf("%lld",ans+minn);
    }

    2005: [Noi2010]能量采集

    2005: [Noi2010]能量采集

    x=1ny=1m2×((x,y)1)+1∑x=1n∑y=1m2×((x,y)−1)+1

    之后可得n×m+2x=1ny=1m(x,y)−n×m+2∑x=1n∑y=1m(x,y)

    之后我们直接求解。

    #include<stdio.h>
    long long min(long long x,long long y)
    {
        if(x>y)
            return y;
        return x;
    }
    long long n,m;
    long long f[100001];
    int main()
    {
        scanf("%lld%lld",&n,&m);
        long long ans2=min(n,m),ans=0;
        for(long long i=ans2;i>=1;i--)
        {
            f[i]=(m/i)*(n/i);
            for(long long j=2*i;j<=ans2;j+=i)
                f[i]-=f[j];
            ans+=f[i]*(2*i-1);
        }
        printf("%lld",ans);
    }

    2007: [Noi2010]海拔

    2007: [Noi2010]海拔

    和狼抓兔子有点像,每一点的高度只能为0或1.平面图转对偶图跑最短路。

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define N 1500002
    int S=0,T=1500001;
    int idx;
    int head[N];
    int to[N];
    int val[N];
    int nex[N];
    long long f[N];
    int inq[N];
    int x;
    int n;
    void addedge(int a,int b,int c)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
        val[idx]=c;
    }
    int arr(int x,int y)
    {
        if(x==0||y>n)
            return S;
        if(x>n||y==0)
            return T;
        return (x-1)*n+y;
    }
    struct Point
    {
        int dis,number;
        inline bool operator < (const Point &a) const
        {
            return dis>a.dis;
        }
    };
    priority_queue < Point > q;
    void dijkstra(int S)
    {
        Point tmp;
        tmp.number=S;
        tmp.dis=0;
        for(int i=1;i<N;i++)
            f[i]=1e16;
        f[tmp.number]=0;
        q.push(tmp);
        while(!q.empty())
        {
            int x=q.top().number;
            q.pop();
            if(inq[x])
                continue;
            inq[x]=0;
            for(int i=head[x];i;i=nex[i])
            {
                if(f[to[i]]>f[x]+val[i]&&(!inq[to[i]]))
                {
                    f[to[i]]=f[x]+val[i];
                    tmp.dis=f[to[i]];
                    tmp.number=to[i];
                    q.push(tmp);
                }
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n+1;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&x);
                addedge(arr(i-1,j),arr(i,j),x);
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n+1;j++)
            {
                scanf("%d",&x);
                addedge(arr(i,j),arr(i,j-1),x);
            }
        for(int i=1;i<=n+1;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&x);
                addedge(arr(i,j),arr(i-1,j),x);
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n+1;j++)
            {
                scanf("%d",&x);
                addedge(arr(i,j-1),arr(i,j),x);
            }
        dijkstra(S);
        printf("%lld",f[T]);
        return 0;
    }

    1079: [SCOI2008]着色方案

    1079: [SCOI2008]着色方案

    guangheli的考试题,10分部分分,我直接爆蛋。

    K和Ci都比较小,我们考虑用记忆化搜索。

    Ci为5,所以我们可以把它存进一个桶里,之后6维DP

    f[a][b][c][d][e][last]表示每种颜色的个数以及最后一个数的颜色。

    #include<cstdio>
    long long f[16][16][16][16][16][6];
    long long t[16];
    long long mod=1e9+7;
    int n,x;
    long long dfs(long long a,long long b,long long c,long long d,long long e,long long last)
    {
        if(f[a][b][c][d][e][last]!=0)
            return f[a][b][c][d][e][last];
        if(a+b+c+d+e==0)
            return 1;
        long long ans=0;
        if(a!=0)
            ans+=(a-(last==2))*dfs(a-1,b,c,d,e,1);
        if(b!=0)
            ans+=(b-(last==3))*dfs(a+1,b-1,c,d,e,2);
        if(c!=0)
            ans+=(c-(last==4))*dfs(a,b+1,c-1,d,e,3);
        if(d!=0)
            ans+=(d-(last==5))*dfs(a,b,c+1,d-1,e,4);
        if(e!=0)
            ans+=e*dfs(a,b,c,d+1,e-1,5);
        f[a][b][c][d][e][last]=ans%mod;
        return f[a][b][c][d][e][last];
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            t[x]++;
        }
        printf("%lld",dfs(t[1],t[2],t[3],t[4],t[5],0));
    }

    BZOJ 4326: NOIP2015 运输计划

    把一条边置成0,问最长链的最小值。

    我们可以用倍增LCA构建这棵树,之后差分数组+二分答案解决此题。

    我校OJ卡常,我也没喆

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 300010
    int fa[N][20];
    int head[N];
    int to[N*2];
    int val[N*2];
    int nex[N*2];
    int n,m;
    long long dis[N];
    long long length[N];
    int lu[N],lv[N];
    long long sum;
    int a,b,c;
    int lca[N];
    long long mid;
    int f[N];
    int dep[N];
    int idx;
    void addedge(int a,int b,int c)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
        val[idx]=c;
    }
    void dfs(int x,int f)
    {
        dep[x]=dep[f]+1;
        fa[x][0]=f;
        for(int i=head[x];i;i=nex[i])
            if(to[i]!=f)
            {
                dis[to[i]]=dis[x]+val[i];
                dfs(to[i],x);
            }
    }
    int Lca(int x,int y)
    {
        if(dep[x]<dep[y])
            swap(x,y);
        int deep=dep[x]-dep[y];
        for(int i=19;i>=0;i--)
            if(deep&(1<<i))
                x=fa[x][i];
        for(int i=19;i>=0;i--)
            if(fa[x][i]!=fa[y][i])
                x=fa[x][i],y=fa[y][i];
        if(x==y)
            return x;
        return fa[x][0];
    }
    void dfs2(int x,int fa)
    {
        for(int i=head[x];i;i=nex[i])
            if(to[i]!=fa)
            {
                dfs2(to[i],x);
                f[x]+=f[to[i]];
            }
    }
    bool check(int x)
    {
        int many=0;
        for(int i=1;i<=n;i++)
            f[i]=0;
        for(int i=1;i<=m;i++)
            if(length[i]>mid)
            {
                many++;
                f[lu[i]]++;
                f[lv[i]]++;
                f[lca[i]]-=2;
            }
        dfs2(1,0);
        for(int i=2;i<=n;i++)
            if(f[i]>=many&&sum-dis[i]+dis[fa[i][0]]<=mid)
                return 1;
        return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            addedge(b,a,c);
            addedge(a,b,c);
        }
        dfs(1,0);
        for(int j=1;j<=19;j++)
            for(int i=1;i<=n;i++)
                fa[i][j]=fa[fa[i][j-1]][j-1];
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&lu[i],&lv[i]);
            lca[i]=Lca(lu[i],lv[i]);
            length[i]=dis[lu[i]]+dis[lv[i]]-2*dis[lca[i]];
            sum=max(sum,length[i]);
        }
        long long l=0,r=sum+1;
        while(l<r)
        {
            mid=(l+r)>>1;
            if(check(mid))
                r=mid;
            else
                l=mid+1;
        }
        printf("%lld",l);
    }

    2190: [SDOI2008]仪仗队

    2190: [SDOI2008]仪仗队

    大水题,线筛欧拉函数不要写错哦!

    #include<cstdio>
    #define N 500010
    int n;
    int phi[N];
    bool notprime[N];
    int prime[N];
    int idx;
    long long ans;
    int main()
    {
        scanf("%d",&n);
        for(int i=2;i<=n;i++)
        {
            if(!notprime[i])
                prime[++idx]=i,phi[i]=i-1;
            for(int j=1;j<=idx&&i*prime[j]<=n;j++)
            {
                notprime[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else
                    phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
        for(int i=2;i<n;i++)
            ans+=phi[i];
        if(n==1)
        {
            printf("0");
            return 0;
        }
        printf("%lld",ans*2+3);
    }

    1040: [ZJOI2008]骑士

    1040: [ZJOI2008]骑士

    N个点,N条边显然是个基环树。我们要拆掉所有环之后进行DP

    f[i]表示选择i点及子树最大值

    g[i]表示不选择i点及子树最大值

    最后的答案就是那些环中点g[i]的最大值

    #include<cstdio>
    #define max(a,b) ((a) > (b) ? (a) : (b))
    #define N 2000100
    int n;
    long long fight[N];
    int fa[N];
    int a;
    int head[N];
    int to[N];
    int nex[N];
    int idx;
    int root1,root2;
    long long f[N];
    long long g[N];
    long long ans,ans2;
    int lu[N];
    int lv[N];
    int tot;
    void addedge(int a,int b)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
    }
    int find(int x)
    {
        if(fa[x]!=x)
            fa[x]=find(fa[x]);
        return fa[x];
    }
    void dfs(int x,int fa)
    {
        f[x]=fight[x];
        g[x]=0;
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=fa)
            {
                dfs(to[i],x);
                g[x]+=max(f[to[i]],g[to[i]]);
                f[x]+=g[to[i]];
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            fa[i]=i;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%d",&fight[i],&a);
            int fx=find(i);
            int fy=find(a);
            if(fx!=fy)
            {
                addedge(i,a);
                addedge(a,i);
                fa[fx]=fy;
            }
            else
            {
                lu[++tot]=a;
                lv[tot]=i;
            }
        }
        for(int i=1;i<=tot;i++)
        {
            dfs(lu[i],0);
            ans2=g[lu[i]];
            dfs(lv[i],0);
            ans2=max(g[lv[i]],ans2);
            ans+=ans2;
        }
        printf("%lld",ans);
    }

    BZOJ 2173 整数的lqp拆分

    jiangminghong的考试题,好题就被我手动打表找规律废掉了

    ans[i]=*ans[i-1]+ans[i-2]

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 3000100
    int mod=1e9+7;
    int n;
    long long ans[N];
    int main()
    {
        scanf("%d",&n); 
        ans[1]=1,ans[2]=2,ans[3]=5;
        for(int i=4;i<=n;i++)
            ans[i]=((ans[i-1]*2)%mod+ans[i-2])%mod;
        printf("%lld",ans[n]);
        return 0;
    }

    BZOJ 1131 [POI2008]Sta

    BZOJ 1131 [POI2008]Sta

    我又想起了llq说的扭一扭,这道题就是这么更新的。

    我们先DFS扫一遍,之后对于每个点将其扭到根,它子树的dep都减去1,其他点的dep都加上1.

    之后我们O(n)解决!

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 2000010
    int n;
    int nex[N];
    int to[N];
    int dep[N];
    int size[N];
    int head[N];
    long long ans[N];
    long long ans2;
    int idx;
    int a,b,ans3;
    void addedge(int a,int b)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
    }
    void dfs(int x,int fa)
    {
        size[x]=1;
        dep[x]=dep[fa]+1;
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=fa)
            {
                dfs(to[i],x);
                size[x]+=size[to[i]];
            }
        }
    }
    void pose(int x,int fa)
    {
        ans[x]=ans[fa]-size[x]+(n-size[x]);
        for(int i=head[x];i;i=nex[i])
            if(to[i]!=fa)
                pose(to[i],x);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            addedge(a,b);
            addedge(b,a);
        }
        dfs(1,0);
        for(int i=1;i<=n;i++)
            ans[1]+=dep[i];
        pose(1,1);
        for(int i=1;i<=n;i++)
            if(ans2<ans[i])
            {
                ans2=ans[i];
                ans3=i;
            }
        printf("%d",ans3);
    }

    2208: [Jsoi2010]连通数

    2208: [Jsoi2010]连通数

    JZYshuraK的好想法,刚开始我一眼tarjan,JZYshuraK告诉我直接floyd让我直接蒙圈。

    他说闭包传递+bitset优化可解决。2*108过掉,码量超短。

    #include <cstdio>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    bitset<2010> is[2010];
    char s[2010][2010];
    int ans=0;
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%s",s[i]+1); 
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) 
                if(s[i][j]=='1'||i==j)
                    is[i][j]=true;
        for(int j=1;j<=n;j++)
            for(int i=1;i<=n;i++)
                if(is[i][j])
                    is[i]|=is[j];
         
        for(int i=1;i<=n;i++)
            ans+=is[i].count();
        printf("%d",ans);
        return 0;
    }

    1060: [ZJOI2007]时态同步

    1060: [ZJOI2007]时态同步

    f[i]表示距离i最远点的距离,之后直接裸树形DP

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 1000001
    int n,S;
    int head[N];
    int to[N];
    int nex[N];
    long long val[N];
    long long f[N];
    int a,b;
    long long c;
    int idx;
    long long ans;
    void addedge(int a,int b,long long c)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
        val[idx]=c;
    }
    void dfs(int x,int fa)
    {
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=fa)
            {
                dfs(to[i],x);
                f[x]=max(f[to[i]]+val[i],f[x]);
            }
        }
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=fa)
            {
                ans=ans+f[x]-val[i]-f[to[i]];
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        scanf("%d",&S);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%lld",&a,&b,&c);
            addedge(a,b,c);
            addedge(b,a,c);
        }
        dfs(S,0);
        printf("%lld",ans);
        return 0;
    }

    BZOJ 1077 天平

    1077 [SCOI2008]天平

    floyd跑差分约束,我刚开始还写WA了。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 501
    int n,A,B;
    char s[101][101];
    int mx[501][501];
    int mn[501][501];
    int c1,c2,c3;
    int main()
    {
        scanf("%d%d%d",&n,&A,&B);
        for(int i=1;i<=n;i++)
            scanf("%s",s[i]+1);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(s[i][j]=='+')
                {
                    mn[i][j]=1;
                    mx[i][j]=2;
                }
                else if(s[i][j]=='-')
                {
                    mn[i][j]=-2;
                    mx[i][j]=-1;
                }
                else if(s[i][j]=='?')
                {
                    mn[i][j]=-2;
                    mx[i][j]=2;
                }
                else
                {
                    mn[i][j]=0;
                    mx[i][j]=0;             
                }
            }
            mn[i][i]=0;
            mx[i][i]=0;
        }
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                {
                    if(i==j||i==k||j==k)
                        continue;
                    mn[i][j]=max(mn[i][j],mn[i][k]+mn[k][j]);
                    mx[i][j]=min(mx[i][j],mx[i][k]+mx[k][j]);
                }
        for(int i=1;i<=n;i++)
        {
            if(i==A||i==B)
                continue;
            for(int j=i+1;j<=n;j++)
            {
                if(j==A||j==B)
                    continue;
                if(mn[A][i]>mx[j][B]||mn[A][j]>mx[i][B])
                    c1++;
                if(mx[A][i]<mn[j][B]||mx[A][j]<mn[i][B])
                    c3++;
                if((mn[A][i]==mx[A][i]&&mn[B][j]==mx[B][j]&&mn[A][i]+mx[B][j]==0)||(mn[A][j]==mx[A][j]&&mn[B][i]==mx[B][i]&&mn[A][j]+mx[B][i]==0))
                    c2++;
            }
        }
        printf("%d %d %d",c1,c2,c3);
        return 0;
    }

     BZOJ 5165 树上倍增

    听ysy20021208说是JLOI 2018 D2 T2佛光树改了一个数据范围

    这题直接新建节点跑LCA就OK了

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 3000001
    int n,m,K;
    int f[N][21];
    int dep[N];
    char opt[2];
    int idx=1;
    int x,y;
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])
            swap(x,y);
        int deep=dep[x]-dep[y];
        for(int i=20;i>=0;i--)
            if(deep&(1<<i))
                x=f[x][i];
        for(int i=20;i>=0;i--)
            if(f[x][i]!=f[y][i])
                x=f[x][i],y=f[y][i];
        if(x==y)
            return x;
        return f[x][0];
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",opt);
            if(opt[0]=='A')
            {
                scanf("%d",&x);
                dep[++idx]=dep[x]+1;
                f[idx][0]=x;
                for(int i=1;i<=20;i++)
                {
                    if(!f[idx][i-1])
                        break;
                    f[idx][i]=f[f[idx][i-1]][i-1];
                }
            }
            if(opt[0]=='Q')
            {
                scanf("%d",&K);
                K--;
                scanf("%d",&x);
                while(K--)
                {
                    scanf("%d",&y);
                    if(x!=1)
                        x=lca(x,y);
                }
                printf("%d
    ",x);
            }
        }
    }

    BZOJ 2705 Longge的问题

    欧拉函数好题

    从老师PPT直接摘下

    #include<cstdio>
    typedef long long ll;
    ll n;
    ll ans;
    ll oula(ll n)
    {
        ll ans=n;
        for(int i=2;i*i<=n;i++)
        {
            if(n%i==0)
            {
                ans=ans/i*(i-1);
                while(n%i==0)
                    n/=i;
            }
        }
        if(n>1)
            ans=ans/n*(n-1);
        return ans;
    }
    int main()
    {
        scanf("%lld",&n);
        for(int i=1;i*i<=n;i++)
            if(n%i==0)
            {
                ans+=oula(n/i)*i;
                if(i*i<n)
                    ans+=(n/i)*oula(i);
            }
        printf("%lld",ans);
        return 0;
    }

    BZOJ 4800 [Ceoi2015]Ice Hockey World Championship

    n<=40,一眼 Meet in the middle,分成两个序列之后二分

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    ll n;
    ll m;
    ll a[1<<22];
    ll b[1<<22];
    ll idx1,idx2;
    ll val[44];
    ll ans;
    void dfs(ll dep,ll n,ll m,ll sum)
    {
        if(sum>m)
            return ;
        if(dep>n)
        {
            a[++idx1]=sum;
            return ;
        }
        dfs(dep+1,n,m,sum);
        dfs(dep+1,n,m,sum+val[dep]);
    }
    void dfs2(ll dep,ll n,ll m,ll sum)
    {
        if(sum>m)
            return ;
        if(dep>n)
        {
            b[++idx2]=sum;
            return ;
        }
        dfs2(dep+1,n,m,sum);
        dfs2(dep+1,n,m,sum+val[dep]);
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=n;i++)
            scanf("%lld",&val[i]);
        dfs(1,n>>1,m,0);
        dfs2((n>>1)+1,n,m,0);
        sort(a+1,a+idx1+1);
        sort(b+1,b+idx2+1);
        for(ll i=1;i<=idx2;i++)
        {
            if(m-b[i]>=a[idx1])
                ans+=idx1;
            else
                ans+=upper_bound(a+1,a+idx1+1,m-b[i])-a-1;        
        }
        printf("%lld",ans);
    }

    BZOJ 1430 小猴打架

    通过这道题我学会了一个新知识点--Prufer序列

    显然,对于N个节点的生成树,种类有N^(N-2),因为这道题对与打架顺序还要重复计算,所以再来个N!/N,也即是(N-1)!,所以F(x)=(x-1)!*x^(x-2)

    #include<cstdio>
    typedef long long ll;
    ll mod=9999991;
    ll n,ans=1;
    int main()
    {
        scanf("%lld",&n);
        for(int i=1;i<=n-2;i++)
            ans=(ans*n)%mod;
        for(int i=2;i<n;i++)
            ans=(ans*i)%mod;
        printf("%lld",ans);
    }

    BZOJ 4173 数学

    结果是phi(n)*phi(m)*n*m

    #include<cstdio>
    typedef long long ll;
    ll mod=998244353;
    ll n,m;
    ll ans;
    ll phi(ll n)
    {
        ll ans=n;
        for(ll i=2;i*i<=n;i++)
        {
            if(n%i==0)
            {
                ans=ans/i*(i-1);
                while(n%i==0)
                    n/=i;
            }
        }
        if(n!=1)
            ans=ans/n*(n-1);
        return ans%mod;
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        ans=phi(n)*phi(m)%mod*(n%mod)%mod*(m%mod)%mod;
        printf("%lld",ans);
        return 0;
    }

    BZOJ 3517 翻硬币

    好题一道,刚开始一眼高斯消元解异或方程组。后来才看出来

    设is[i][j]为此状态翻不翻。决定这个点只有这一行与这一列的情况,我们求一个前缀异或值,倒过来就是1的状态

    #include<cstdio>
    int n;
    int a[1001][1001];
    int is[1001][1001];
    int row[1001];
    int column[1001];
    int ans;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%1d",&a[i][j]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                row[i]^=a[i][j];
                column[j]^=a[i][j];
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                int tmp=row[i]^column[j];
                tmp^=a[i][j];
                ans+=tmp;
            }
        if(ans>n*n-ans)
            ans=n*n-ans;
        printf("%d",ans);
    }

    BZOJ 2438: [中山市选2011]杀人游戏

    tarjan缩点+判断,有坑。最后一个缩块入度为0并且只有一个点答案-1

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 300010
    int tot;
    int nex[N<<1];
    int to[N<<1];
    int head[N<<1];
    int dep[N];
    int low[N];
    int blob[N];
    int stack[N];
    int vis[N];
    int inz[N];
    int top;
    int cnt,idx;
    int sum;
    int in[N];
    int inblob[N];
    int n,m;
    int x,y;
    int ans;
    void addedge(int a,int b)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
    }
    void tarjan(int x)
    {
        dep[x]=low[x]=++cnt;
        stack[++top]=x;
        vis[x]=inz[x]=1;
        for(int i=head[x];i;i=nex[i])
        {
            if(!vis[to[i]])
            {
                tarjan(to[i]);
                low[x]=min(low[x],low[to[i]]);
            }
            else if(inz[to[i]])
                low[x]=min(low[x],dep[to[i]]);
        }
        if(dep[x]==low[x])
        {
            int here;
            sum++;
            do
            {
                here=stack[top--];
                blob[here]=sum;
                inz[here]=0;
                in[sum]++;
            }while(here!=x);
        }
    }
    bool is(int x)
    {
        int i;
        bool flag=1;
        for(i=head[x];i;i=nex[i])
            inblob[blob[to[i]]]--;
        for(i=head[x];i;i=nex[i])
            if(!inblob[blob[to[i]]])
                flag=0;
        for(i=head[x];i;i=nex[i])
            inblob[blob[to[i]]]++;
        return flag;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            addedge(x,y);
        }
        for(int i=1;i<=n;i++)
            if(!vis[i])
                tarjan(i);
        for(int x=1;x<=n;x++)
            for(int i=head[x];i;i=nex[i])
                if(blob[x]!=blob[to[i]])
                    inblob[blob[to[i]]]++;
        for(int i=1;i<=sum;i++)
            if(!inblob[i])
                ans++;
        int i;
        for(i=1;i<=n;i++)
            if(in[blob[i]]==1&&!inblob[blob[i]]&&is(i))
                break;
        if(i<=n)
            ans--;
        printf("%.6lf
    ",(double)(n-ans)/n);
        return 0;
    }

    BZOJ 5085 最大

    这题思维难度较大,二分+枚举线段

    总时间O(n2logmaxlongint)

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int boom[1001][1001];
    int a[1001][1001];
    int tot,cnt[1001];
    int n,m;
    int l=0x7f7f7f7f,r=0,mid;
    int ans;
    bool check(int mid)
    {
        memset(boom,0,sizeof(boom));
        for(int i=1;i<=n;i++)
        {
            tot=0;
            for(int j=1;j<=m;j++)
                if(a[i][j]>=mid)
                    cnt[++tot]=j;
            for(int j=1;j<=tot;j++)
                for(int k=j+1;k<=tot;k++)
                {
                    if(boom[cnt[j]][cnt[k]]==1)
                        return 1;
                    boom[cnt[j]][cnt[k]]=1;
                }
        }
        return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&a[i][j]);
                l=min(l,a[i][j]);
                r=max(r,a[i][j]);
            }
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(check(mid))
                l=mid+1,ans=mid;
            else
                r=mid;
        }
        printf("%d",ans);
        return 0;
    }

    BZOJ 1954 The Xor-longest Path

    Trie树题目,dfs边权时变成异或

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 1500010
    int n;
    int a,b,c;
    int head[N];
    int to[2*N];
    int val[2*N];
    int nex[2*N];
    int ch[N][2];
    int dis[N];
    int cnt;
    int ans;
    int idx;
    void addedge(int a,int b,int c)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
        val[idx]=c;
    }
    void trie(int x)
    {
        int here=0;
        bool is;
        for(int i=30;i>=0;i--)
        {
            if(x&(1<<i))
                is=1;
            else
                is=0;
            if(!ch[here][is])
                ch[here][is]=++cnt;
            here=ch[here][is];
        }
    }
    void dfs(int x,int fa)
    {
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=fa)
            {
                dis[to[i]]=dis[x]^val[i];
                dfs(to[i],x);
            }
        }
    }
    int find(int x)
    {
        int here=0,ans=0;
        for(int i=30;i>=0;i--)
        {
            int is=x&(1<<i)?1:0;
            if(ch[here][!is])
                ans|=(1<<i),here=ch[here][!is];
            else
                here=ch[here][is];
        }
        return ans;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            addedge(a,b,c);
            addedge(b,a,c);
        }
        dfs(1,0);
        for(int i=1;i<=n;i++)
        {
            trie(dis[i]);
            ans=max(ans,find(dis[i]));
        }
        printf("%d",ans);
    }

    BZOJ 3251树上三角形

    总共fib数列也没几个数,直接暴力LCA更新就OK

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 1000100
    int n,Q;
    int val[N];
    int fa[N];
    int a,b;
    int head[N];
    int to[N];
    int nex[N];
    int dep[N];
    int idx=1;
    int ans[N];
    int tot;
    void addedge(int a,int b)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
    }
    void dfs(int x)
    {
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=fa[x])
            {
                dep[to[i]]=dep[x]+1;
                dfs(to[i]);
            }
        }
    }
    bool go(int x,int y)
    {
        if(dep[x]<dep[y])
            swap(x,y);
        tot=0;
        while(dep[x]>dep[y])
        {
            ans[++tot]=val[x];
            x=fa[x];
            if(tot>50)
                return 1;
        }
        while(x!=y)
        {
            ans[++tot]=val[x];
            ans[++tot]=val[y];
            x=fa[x];
            y=fa[y];
            if(tot>50)
                return 1;
        }
        ans[++tot]=val[x];
        sort(ans+1,ans+tot+1);
        for(int i=3;i<=tot;i++)
        {
            if(ans[i]-ans[i-2]<ans[i-1])
                return 1;
        }
        return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&Q);
        for(int i=1;i<=n;i++)
            scanf("%d",&val[i]);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            addedge(a,b);
            fa[b]=a;
        }
        dfs(1);
        while(Q--)
        {
            int opt;
            scanf("%d",&opt);
            if(opt==0)
            {
                scanf("%d%d",&a,&b);
                if(go(a,b))
                    puts("Y");
                else
                    puts("N");
            }
            else
            {
                scanf("%d%d",&a,&b);
                val[a]=b;
            }
        }
    }

    BZOJ 2523 聪明的学生

    强大的题目,贼神奇,其实是个迭代的过程

    #include<cstdio>
    using namespace std;
    int n,m,last[3]={2,0,1},nex[3]={1,2,0},ans[30005][3],Ans,num;
    void work(int x,int y,int t)
    {
        if(Ans>n)
            return;
        if(x==y)
        {
            Ans+=t+1;
            return;
        }
        if(x>y)
        {
            Ans+=2;
            work(y,x-y,nex[t]);
        }
        else
        {
            Ans++;
            work(y-x,x,last[t]);
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)&&n!=-1)
        {
            num=0;
            for(int i=1;i<m;i++)
            {
                int j=m-i;
                Ans=0;
                work(i,j,(n-1)%3);
                if(Ans==n)
                    ans[++num][nex[(n-1)%3]]=i,ans[num][(n-1)%3]=m,ans[num][last[(n-1)%3]]=j;
            }
            printf("%d
    ",num);
            if((n-1)%3==1)
                for(int i=num;i>0;i--)
                    printf("%d %d %d
    ",ans[i][0],ans[i][1],ans[i][2]);
            else
                for(int i=1;i<=num;i++)
                    printf("%d %d %d
    ",ans[i][0],ans[i][1],ans[i][2]);
        }
        return 0;
    }

    BZOJ 4668 冷战

    并查集路径压缩+启发式合并&LCA

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 1000100
    int n,m;
    int ans[N];
    int fa[N];
    int size[N];
    int idx;
    int lastans;
    int ti[N];
    int dep[N];
    int tim=0;
    int x,y;
    int find(int x)
    {
        int f;
        if(fa[x]==x)
            return fa[x];
        else
        {
            f=find(fa[x]);
            dep[x]=dep[fa[x]]+1;
        }
        return f;
    }
    void merge(int x,int y,int i)
    {
        int fx=find(x);
        int fy=find(y);
        if(fx!=fy)
        {
            if(size[fx]>size[fy])
                swap(fx,fy);    
            fa[fx]=fy;
            size[fy]+=fx;
            ti[fx]=i;
        }
    }
    int lca(int x,int y)
    {
        int fx=find(x);
        int fy=find(y);
        if(fx!=fy)
            return 0;
        int ans=0; 
        if(dep[x]<dep[y])
            swap(x,y);
        while(dep[x]>dep[y])
        {
            ans=max(ans,ti[x]);
            x=fa[x];
        }
        while(x!=y)
        {
            ans=max(ans,ti[x]);
            ans=max(ans,ti[y]);
            x=fa[x];
            y=fa[y];
        }
        return ans;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            fa[i]=i,size[i]=1;
        int opt;
        for(int i=1;i<=m;i++)
        {   
            scanf("%d",&opt);
            if(!opt)
            {
                scanf("%d%d",&x,&y);
                x=lastans^x;
                y=lastans^y;
                merge(x,y,++tim);
            }
            else
            {
                scanf("%d%d",&x,&y);
                x=lastans^x;
                y=lastans^y;
                int ans=lca(x,y);
                printf("%d
    ",ans);
                lastans=ans;            
            }
        }
        return 0;
    }

    BZOJ 3252: 攻略

    ysy20021208的考试题。

    我们可以长链剖分直接解决这个问题,取K条最长链

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 500010
    int to[N];
    int head[N];
    int nex[N];
    int son[N];
    long long dep[N];
    int a[N];
    int fa[N];
    long long mx[N];
    int n,K;
    int x,y;
    int idx;
    long long lian[N];
    int que[N];
    int cnt;
    long long ans;
    bool cmp(int x,int y)
    {
        return lian[x]>lian[y];
    }
    void addedge(int a,int b)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
    }
    void dfs(int x,int f)
    {
        dep[x]=dep[f]+a[x];
        fa[x]=f;
        mx[x]=dep[x];
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=fa[x])
            {
                dfs(to[i],x);
                mx[x]=max(mx[x],mx[to[i]]);
                if(mx[to[i]]>mx[son[x]])
                    son[x]=to[i];
            }
        }
    }
    void dfs2(int x,int t)
    {
        lian[t]+=a[x];
        if(son[x])
            dfs2(son[x],t);
        for(int i=head[x];i;i=nex[i])
        {
            if(to[i]!=fa[x]&&to[i]!=son[x])
            {
                que[++cnt]=to[i];
                dfs2(to[i],to[i]);
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&K);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            addedge(x,y);
            addedge(y,x);
        }
        dfs(1,0);
        que[++cnt]=1;
        dfs2(1,1);
        sort(que+1,que+cnt+1,cmp);
        for(int i=1;i<=K;i++)
            ans+=lian[que[i]];
        printf("%lld",ans);
    }

    BZOJ 1452 JSOI2009 Count

    二维树状数组直接解决修改&查询问题

    #include<cstdio>
    int f[301][301][101];
    int map[301][301];
    int n,m;
    int x,y,c;
    int x1,x2,y1,y2;
    int lowbit(int x){return x&-x;}
    void update(int x,int y,int val,int delta)
    {
        for(int i=x;i<=n;i+=lowbit(i))
            for(int j=y;j<=m;j+=lowbit(j))
                f[i][j][val]+=delta;
    }
    int query(int x,int y,int val)
    {
        int ans=0;
        for(int i=x;i;i-=lowbit(i))
            for(int j=y;j;j-=lowbit(j))
                ans+=f[i][j][val];
        return ans;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&map[i][j]);
                update(i,j,map[i][j],1);
            }
        int Q,opt;
        scanf("%d",&Q);
        while(Q--)
        {
            int ans=0;
            scanf("%d",&opt);
            if(opt==1)
            {
                scanf("%d%d%d",&x,&y,&c);
                update(x,y,map[x][y],-1);
                map[x][y]=c;
                update(x,y,c,1);
            }
            else
            {
                scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c);
                ans=ans+query(x2,y2,c)-query(x1-1,y2,c)-query(x2,y1-1,c)+query(x1-1,y1-1,c);
                printf("%d
    ",ans);
            }
        }
    }

    BZOJ 1485 有趣的数列

    和括号序一样的Catlan数。

    之后不让直接求md

    #include<cstdio>
    #define N 2000001
    long long n,P;
    long long prime[N];
    bool notprime[N];
    int idx;
    long long pos[N];
    long long f[N];
    long long ans=1;
    void change(int x,int delta)
    {
        while(x!=1)
        {
            f[prime[pos[x]]]+=delta;
            x/=prime[pos[x]];
        }
    }
    long long pow(long long x,long long y)
    {
        long long ans=1;
        while(y)
        {
            if(y&1)
                ans=(ans*x)%P;
            x=(x*x)%P;
            y>>=1;
        }
        return ans;
    }
    int main()
    {
        scanf("%lld%lld",&n,&P);
        for(int i=2;i<=2*n;i++)
        {
            if(!notprime[i])
                prime[++idx]=i,pos[i]=idx;
            for(int j=1;j<=idx&&i*prime[j]<=2*n;j++)
            {
                notprime[i*prime[j]]=1;
                pos[i*prime[j]]=j;
                if(i%prime[j]==0)
                    break;
            }
        }
        for(int i=n+2;i<=2*n;i++)
            change(i,1);
        for(int i=1;i<=n;i++)
            change(i,-1);
        for(int i=1;i<=idx;i++)
            if(f[prime[i]])
                ans=ans*pow(prime[i],f[prime[i]])%P;
        printf("%lld",ans%P);
    }

    BZOJ 2259新型计算机

    刚开始就想最短路了,但是只拿了50分暴力

    100分的建图非常神奇了

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<cstring>
    using namespace std;
    #define N 4000100
    int n;
    int x;
    int head[N];
    int to[N];
    int val[N];
    int nex[N];
    int f[N];
    int vis[N];
    int vis2[N];
    int idx;
    void addedge(int a,int b,int c)
    {
        nex[++idx]=head[a];
        head[a]=idx;
        to[idx]=b;
        val[idx]=c;
    }
    struct Point
    {
        int number,dis;
        inline bool operator < (const Point &a)const
        {
            return dis>a.dis;
        }
    };
    priority_queue <Point> q;
    void dijkstra(int S)
    {
        memset(f,0x3f,sizeof(f));
        Point tmp;
        tmp.number=S;
        tmp.dis=0;
        f[S]=0;
        q.push(tmp);
        while(!q.empty())
        {
            int x=q.top().number;
            q.pop();
            for(int i=head[x];i;i=nex[i])
            {
                if(f[to[i]]>f[x]+val[i])
                {
                    f[to[i]]=f[x]+val[i];
                    tmp.dis=f[to[i]];
                    tmp.number=to[i];
                    q.push(tmp);
                }
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            for(int j=i+1;j<=min(i+x+1,n)&&(!vis[j]);j++)
                vis[j]=1,addedge(j,j-1,1);
            for(int j=i+x+1;j<=n&&!vis2[j];j++)
                vis2[j]=1,addedge(j,j+1,1);
            if(i+x+1<=n+1)
                addedge(i,i+x+1,0);
            else
                addedge(i,n+1,i+x-n);
        }
        dijkstra(1);
        printf("%d",f[n+1]);
        return 0;
    }

    BZOJ 1047 理想的正方形

    二维RMQ解决,并不是单调队列

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define N 1010
    int f[11][N][N],f2[11][N][N];
    int ans=2e9;
    int map[N][N];
    int minn,maxn;
    int a,b,n;
    int k;
    int main()
    {
        scanf("%d%d%d",&a,&b,&n);
        for(int i=1;i<=a;i++)
            for(int j=1;j<=b;j++)
            {
                scanf("%d",&map[i][j]);
                f[0][i][j]=f2[0][i][j]=map[i][j];
            }
        for(k=1;(1<<k)<=n;k++)
            for(int i=1;i<=a-(1<<k)+1;i++)
                for(int j=1;j<=b-(1<<k)+1;j++)
                {
                    f[k][i][j]=max(max(f[k-1][i+(1<<(k-1))][j],f[k-1][i][j]),max(f[k-1][i][j+(1<<(k-1))],f[k-1][i+(1<<(k-1))][j+(1<<(k-1))]));
                    f2[k][i][j]=min(min(f2[k-1][i+(1<<(k-1))][j],f2[k-1][i][j]),min(f2[k-1][i][j+(1<<(k-1))],f2[k-1][i+(1<<(k-1))][j+(1<<(k-1))]));
                }
        for(int i=1;i<=a-n+1;i++)
            for(int j=1;j<=b-n+1;j++)
            {
                maxn=max(max(f[k-1][i][j],f[k-1][i][j+n-(1<<(k-1))]),max(f[k-1][i+n-(1<<(k-1))][j],f[k-1][i+n-(1<<(k-1))][j+n-(1<<(k-1))]));
                minn=min(min(f2[k-1][i][j],f2[k-1][i][j+n-(1<<(k-1))]),min(f2[k-1][i+n-(1<<(k-1))][j],f2[k-1][i+n-(1<<(k-1))][j+n-(1<<(k-1))]));
                ans=min(ans,maxn-minn);
            }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    Leetcode Binary Tree Level Order Traversal
    Leetcode Symmetric Tree
    Leetcode Same Tree
    Leetcode Unique Paths
    Leetcode Populating Next Right Pointers in Each Node
    Leetcode Maximum Depth of Binary Tree
    Leetcode Minimum Path Sum
    Leetcode Merge Two Sorted Lists
    Leetcode Climbing Stairs
    Leetcode Triangle
  • 原文地址:https://www.cnblogs.com/342zhuyongqi/p/9935077.html
Copyright © 2011-2022 走看看