zoukankan      html  css  js  c++  java
  • 百度之星 初赛 BC

    HDU  5691

    这B题目 一看就知道不会 

    看题解  听说是状态 压缩  立刻就不想写了  今天状态好点 写一下

    dp[i][j]   代表 i 这个状态  第j个当做结尾插入的  最大的加起来的和

    初始化也很神奇

    先初始化没每个状态的1的个数 然后转移  列举前一个 这个 

    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    using namespace std;
    
    #define LL   __int64
    #define MAXN 10010
    #define inf  1000000000
    
    int cnt[(1<<16)+10];
    int dp[(1<<16)+10][17];
    int z[20],p[20];
    
    int main()
    {
        int t,ca;
        scanf("%d",&t);
        for(int i=1;i<=(1<<16);i++)
        {
            int a=i;
            while(a>0)
            {
                if(a%2==1)
                    cnt[i]++;
                a=a/2;
            }
        }
        ca=1;
        while(t--)
        {
            int n;
            scanf("%d",&n);
            for(int i=0;i<n;i++)
                scanf("%d %d",&z[i],&p[i]);
            for(int i=0;i<(1<<n);i++)
                for(int j=0;j<=n;j++)
                    dp[i][j]=-inf;
            z[n]=0;
            dp[0][n]=0;
    
            for(int i=0;i<(1<<n);i++)
            {
                for(int j=0;j<=n;j++)
                    if(dp[i][j]!=-inf)
                        for(int k=0;k<n;k++)
                        {
                            if(((1<<k)&i)==0&&(p[k]==-1||p[k]==cnt[i]))
                                dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+z[j]*z[k]);
                        }
            }
            int ans=-inf;
            for(int i=0;i<n;i++)
                ans = max(ans,dp[(1<<n)-1][i]);
            printf("Case #%d:
    %d
    ",ca++,ans);
        }
        return 0;
    }
    View Code

    HDU 5692

    唯一的缺点就是没看到这是一棵树  0 开始到某个要去的点 显然不可能回来   哈哈哈  最多就只能走下去

    感觉做过类似的  dfs 把每个点走一下标上号  然后 算出每个点到 父亲的距离  然后 转化到线段树上 

    怎么建树呢  1-n  带表 dfs序列  查询这个点就是 查询这个点 包括的子树的 l r    然后这个在dfs的时候就 处理出来了

    然后 更新呢  就是 lazy   子树都要更新 

    更新的权值呢    y-w[b]   w[b]=y  真厉害    long long   哈哈哈 

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    using namespace std;
    
    #define ll  __int64
    #define MAXN 100010
    #define inf  1000000000000
    
    int head[MAXN];
    struct  edg
    {
        int to,next;
    }edge[MAXN*2];
    int cnt,num;
    ll w[MAXN],dis[MAXN],ls[MAXN],rs[MAXN],ind[MAXN];
    void add(int u,int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    struct node
    {
        int l,r;
        ll w,lz;
    }tree[MAXN<<2];
    
    void dfs(int u,int fa)
    {
        num++;
        ls[u]=num;
        ind[num]=u;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(v==fa)
                continue;
            dis[v]=dis[u]+w[v];
            dfs(v,u);
        }
        rs[u]=num;
    }
    void Push_down(int a)
    {
        tree[a<<1].lz+=tree[a].lz;
        tree[a<<1].w+=tree[a].lz;
        tree[a<<1|1].lz+=tree[a].lz;
        tree[a<<1|1].w+=tree[a].lz;
        tree[a].lz=0;
    }
    void Push_up(int a)
    {
        tree[a].w=max(tree[a<<1].w,tree[a<<1|1].w);
    }
    void Build(int l,int r,int a)
    {
        tree[a].l=l;
        tree[a].r=r;
        tree[a].lz=0;
        if(l==r)
        {
            tree[a].w=dis[ind[l]];
            return ;
        }
        int mid=(l+r)>>1;
        Build(l,mid,a<<1);
        Build(mid+1,r,a<<1|1);
        Push_up(a);
    }
    void Update(int l,int r,int l1,int r1,ll w1,int a)
    {
        if(l1<=l&&r<=r1)
        {
            tree[a].w+=w1;
            tree[a].lz+=w1;
            return ;
        }
        int mid=(l+r)>>1;
        if(tree[a].lz)
            Push_down(a);
        if(l1<=mid)
            Update(l,mid,l1,r1,w1,a<<1);
        if(r1>mid)
            Update(mid+1,r,l1,r1,w1,a<<1|1);
        Push_up(a);
    }
    ll Ques(int l,int r,int l1,int r1,int a)
    {
        ll mx=-inf;
        if(l1<=l&&r<=r1)
        {
            return tree[a].w;
        }
        int mid=(l+r)>>1;
        if(tree[a].lz)
            Push_down(a);
        if(l1<=mid)
            mx=max(mx,Ques(l,mid,l1,r1,a<<1));
        if(r1>mid)
            mx=max(mx,Ques(mid+1,r,l1,r1,a<<1|1));
        return mx;
    }
    int main()
    {
        int t,ca;
        ca=1;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            memset(head,-1,sizeof(head));
            cnt=0;
            for(int i=1;i<n;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                add(a,b);
                add(b,a);
            }
            for(int i=0;i<n;i++)
                scanf("%I64d",&w[i]);
            num=0;
            dis[0]=w[0];
            dfs(0,-1);
            Build(1,num,1);
            printf("Case #%d:
    ",ca++);
            while(m--)
            {
                int way;
                scanf("%d",&way);
                if(way==1)
                {
                    int a;
                    scanf("%I64d",&a);
                    printf("%I64d
    ",Ques(1,n,ls[a],rs[a],1));
                }
                else
                {
                    int a;
                    ll b;
                    scanf("%d%I64d",&a,&b);
                    Update(1,n,ls[a],rs[a],b-w[a],1);
                    w[a]=b;
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    后缀数组-另辟蹊径
    Project Euler 不定期更新
    Educational Codeforces Round 93 (Rated for Div. 2)
    Codeforces Round #664 (Div. 2)
    lower_bound和upper_bound的用法
    Codeforces Round #663 (Div. 2)
    Codeforces Round #661 (Div. 3)
    质数笔记
    C++运算符的优先级
    图的构建
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6591821.html
Copyright © 2011-2022 走看看