• BZOJ2783: [JLOI2012]树(树上前缀和+set)


    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 1215  Solved: 768
    [Submit][Status][Discuss]

    Description

    数列
    提交文件:sequence.pas/c/cpp
    输入文件:sequence.in
    输出文件:sequence.out
    问题描述:
    把一个正整数分成一列连续的正整数之和。这个数列必须包含至少两个正整数。你需要求出这个数列的最小长度。如果这个数列不存在则输出-1。
    输入格式:
    每行包含一个正整数n。
    每个文件包含多行,读入直到文件结束。
    输出格式:
    对于每个n,输出一行,为这个数列的最小长度。
     

           第一行是两个整数N和S,其中N是树的节点数。

           第二行是N个正整数,第i个整数表示节点i的正整数。

           接下来的N-1行每行是2个整数x和y,表示y是x的儿子。

    输出格式:

           输出路径节点总和为S的路径数量。

     

    输入样例:

    输出样例:

    3 3

    1 2 3

    1 2

    1 3

    2

     

    数据范围:

    对于30%数据,N≤100;

    对于60%数据,N≤1000;

    对于100%数据,N≤100000,所有权值以及S都不超过1000。

    数据范围:
    对于所有数据,n≤263

    这个是JLOI2012的T1,发出来仅为了试题完整

    =============================================================================================

           在这个问题中,给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。

    Input

           第一行是两个整数N和S,其中N是树的节点数。

           第二行是N个正整数,第i个整数表示节点i的正整数。

           接下来的N-1行每行是2个整数x和y,表示y是x的儿子。

    Output

           输出路径节点总和为S的路径数量。

     

     

    Sample Input

    3 3

    1 2 3

    1 2

    1 3

    Sample Output

    2

    HINT

    对于100%数据,N≤100000,所有权值以及S都不超过1000。

    Source

    刚开始以为是点分治,但是这道题目明确说明所有的路径都是一条链

    然后来一遍树上前缀和就行了!

    注意不要忘了删除

    #include<cstdio>
    #include<set>
    #include<algorithm>
    #include<cstring>
    #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<23,stdin),p1==p2)?EOF:*p1++)
    char buf[1<<23],*p1=buf,*p2=buf;
    using namespace std;
    const int MAXN=1e6+10;
    inline int read()
    {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int N,S;
    int val[MAXN],sum[MAXN],ans=0;
    set<int>s;
    struct node
    {
        int u,v,nxt;
    }edge[MAXN];
    int head[MAXN],num=1;
    inline void AddEdge(int x,int y)
    {
        edge[num].u=x;
        edge[num].v=y;
        edge[num].nxt=head[x];
        head[x]=num++;
    }
    int dfs(int now)
    {
        s.insert(sum[now]);
        if(s.find(sum[now]-S)!=s.end()) ans++;
        for(int i=head[now];i!=-1;i=edge[i].nxt)
        {
            sum[edge[i].v]=sum[now]+val[edge[i].v];
            dfs(edge[i].v);
        }
        s.erase(s.find(sum[now]));
    }
    int main()
    {
        #ifdef WIN32
        freopen("a.in","r",stdin);
        #endif
        N=read(),S=read();
        memset(head,-1,sizeof(head));
        for(int i=1;i<=N;i++) val[i]=read();
        for(int i=1;i<=N-1;i++)
        {
            int x=read(),y=read();
            AddEdge(x,y);
        }
        sum[1]=val[1];
        //s.insert(0);
        dfs(1);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    [数学-构造矩阵]NEFU 1113
    设计模式【1】:原型模式【创建对象】
    XML(五)dom4j增删改查
    小规则让你写出美丽又高效的程序
    jQuery源代码解析(3)—— ready载入、queue队列
    cocos2d-Lua02Lua面向对象
    在Linux下用make指令编译进度条程序。
    JS两日期相减
    java debugger
    tomcat server.xml
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8692950.html
Copyright © 2020-2023  润新知