zoukankan      html  css  js  c++  java
  • ACdream 1028 Path

    先思考一下序列上应该怎么做。

    如果某段和为x,并且x为偶数,那么比x小的偶数,一定是这段的子段。

    如果某段和为x,并且x为奇数,那么比x小的奇数,一定是这段的子段。

    因此....只要寻找最大的连续的和为奇数的是多少,偶数的是多少。然后对询问就可以o(1)输出了。

    推广到树上,就是只要计算路径上最大的奇数和最大的偶数。 树dp即可解决。 树dp写搓了。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    #include<ctime>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0);
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    
    int n,q;
    bool f[200010],L[200010];
    struct Edge
    {
        int u,v,w,nx;
    }e[200010];
    int sz,h[100010];
    
    int mx[100010][2];
    int max0,max1;
    int a[100];
    
    struct X
    {
        int from, num;
        X()
        {
            num = 0;
            from = 0;
        }
        X(int From,int Num)
        {
            from=From;
            num=Num;
        }
        bool operator < (const X &a) const {
            return num<a.num;
        }
    };
    
    void add(int a,int b,int c)
    {
        e[sz].u=a; e[sz].v=b; e[sz].w=c; e[sz].nx=h[a]; h[a]=sz++;
    }
    
    struct cmp{
        bool operator ()(int &a,int &b)
        {
            return a<b;
        }
    };
    
    void dfs(int x)
    {
        f[x]=1;
    
        priority_queue<X>Q[3];
    
        for(int i=h[x];i!=-1;i=e[i].nx)
        {
            if(f[e[i].v]==1) continue;
    
            mx[x][e[i].w%2]=e[i].w;
    
            dfs(e[i].v);
    
            if(mx[e[i].v][0]!=-1) Q[(e[i].w+mx[e[i].v][0])%2].push(X(e[i].v,e[i].w+mx[e[i].v][0]));
            if(mx[e[i].v][1]!=-1) Q[(e[i].w+mx[e[i].v][1])%2].push(X(e[i].v,e[i].w+mx[e[i].v][1]));
    
            if(mx[e[i].v][0]==-1||mx[e[i].v][1]==-1)
            {
                if(Q[(e[i].w)%2].empty()) Q[(e[i].w)%2].push(X(e[i].v,e[i].w));
            }
        }
    
    
        if(!Q[0].empty()) mx[x][0]=Q[0].top().num;
        if(!Q[1].empty()) mx[x][1]=Q[1].top().num;
    
        int p=0;
    
        X f1,f2,g1,g2;
        if(!Q[0].empty()) { f1=Q[0].top(); Q[0].pop(); }
        if(!Q[0].empty()) { f2=Q[0].top(); Q[0].pop(); }
    
        if(!Q[1].empty()) { g1=Q[1].top(); Q[1].pop(); }
        if(!Q[1].empty()) { g2=Q[1].top(); Q[1].pop(); }
    
        if(f1.num+f2.num!=0) a[p++]=f1.num+f2.num;
        if(g1.num+g2.num!=0) a[p++]=g1.num+g2.num;
    
        if(f1.from!=g1.from)
        {
            if(f1.num+g1.num!=0) a[p++]=f1.num+g1.num;
        }
    
        else
        {
            if(f1.num+g2.num!=0) a[p++]=f1.num+g2.num;
            if(f2.num+g1.num!=0) a[p++]=f2.num+g1.num;
        }
    
        for(int i=0;i<p;i++)
        {
            if(a[i]%2==0) max0=max(max0,a[i]);
            if(a[i]%2==1) max1=max(max1,a[i]);
        }
    
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&q))
        {
            memset(f,sz=0,sizeof f);
            memset(h,-1,sizeof h);
            memset(L,0,sizeof L);
    
            for(int i=1;i<n;i++)
            {
                int u,v,w; scanf("%d%d%d",&u,&v,&w);
                add(u,v,w); add(v,u,w);
            }
    
            memset(mx,-1,sizeof mx);
            max0=max1=-1; dfs(1);
            for(int i=1;i<=q;i++)
            {
                int x; scanf("%d",&x);
                if(x<0) printf("No
    ");
                else
                {
                    if(x%2==0)
                    {
                        if(max0>=x) printf("Yes
    ");
                        else printf("No
    ");
                    }
                    if(x%2==1)
                    {
                        if(max1>=x) printf("Yes
    ");
                        else printf("No
    ");
                    }
                }
            }
    
        }
        return 0;
    }
  • 相关阅读:
    ORA-01940: cannot drop a user that is currently connected解决方法
    Git基本用法简介
    C 入门 第十节 存储区
    C 入门 第九节 结构体指针
    C 入门 第八节 指针
    C 入门 第七节 结构体
    C 入门 第六节 自定义函数
    C 入门 第五节 多维数组 字符串数组
    C 入门 第四节
    C 入门 第三节
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5782044.html
Copyright © 2011-2022 走看看