zoukankan      html  css  js  c++  java
  • CF_216_Div_2

    比赛链接:http://codeforces.com/contest/369

    369C - Valera and Elections

    这是一个树上问题,用深搜,最开始贪心想得是只加叶子节点,找到一个叶子节点且从根1 ——》 叶子节点有problem edges,就把这个点加入,但后来一直WA,才发现时贪错了,找到的这个叶子节点不一定需要,所以要多记录点信息,参考别人的思想,就是标记每个点是不是需要修,如果一个更深的点需要修,则中间的就不需要了。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    using namespace std;
    
    const int maxn = 1e5+10;
    
    vector< pair<int,int> > G[maxn];
    bool rep[maxn];
    
    void dfs(int u,int fa,int bef)  //bef是从1->u距离u最近的需要修的点,不断更新就行,最开始dfs(1,-1,-1)中bef == 1的原因是一这个点一定不需要修。
    {
        int sz = G[u].size();
    
        for(int i=0; i<sz; i++)
        {
            pair<int,int> my = G[u][i];
            if(my.first == fa) continue;
    
            if(my.second == 2)
            {
                rep[my.first] = true;
                rep[bef] = false;
                dfs(my.first,u,my.first);
            }
            else
                dfs(my.first,u,bef);
        }
    }
    
    int main()
    {
        //freopen("E:\acm\input.txt","r",stdin);
        int n;
        cin>>n;
        for(int i=1; i<n; i++)
        {
            int x,y,t;
            scanf("%d %d %d",&x,&y,&t);
    
            G[x].push_back(make_pair(y,t));
            G[y].push_back(make_pair(x,t));
        }
        memset(rep,0,sizeof(rep));
        dfs(1,-1,1);
    
        int ans = 0;
        for(int i=1; i<=n; i++)
            if(rep[i]) ans++;
        cout<<ans<<endl;
        for(int i=1; i<=n; i++)
            if(rep[i]) cout<<i<<" ";
    }
    View Code

    Tutorial里面的解法没看懂

    369D - Valera and Fools

    只要明白每个situation要么是a[i]到a[n]的连续数列,要么是一个数a[j]+a[i]到a[n]的连续数列,这样情况就少很多,了解了这个,就可以想到用宽搜了

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    const int maxn = 3050;
    
    int p[maxn];
    int sum[maxn];
    bool head[maxn];
    bool man[maxn];
    
    struct Node
    {
        int u,v;
        int round;
        Node(int u=0,int v=0,int round=0):  u(u), v(v), round(round) {}
    };
    
    int main()
    {
       // freopen("E:\acm\input.txt","r",stdin);
    
        int n,k;
        cin>>n>>k;
        for(int i=1; i<=n; i++)
            cin>>p[i];
        sum[n+1] = 0;
        man[n+1] = 0;
        for(int i=n; i>=1; i--)
        {
            sum[i] = sum[i+1] + p[i];
            if(p[i]==100 || man[i+1]) man[i] = 1;
            else                      man[i] = 0;
        }
    
    
        memset(head,0,sizeof(head)); //标记一个连续数列,让它最多出现一次
    
        int ans = 1;
        head[1] = true;
    
        queue< Node > Q;
        Q.push(Node(1,2,0));
    
        while(!Q.empty())
        {
            Node my = Q.front(); Q.pop();
    
            if(my.round >= k) continue;
            int u = my.u;
            int v = my.v;
    
            if(u > n || v > n) continue;
    
    
            if(p[u] > 0 && !man[v])
            {
                ans ++;
                Q.push(Node(u,v+1,my.round+1));
            }
            if(sum[v] > 0 && p[u] != 100 && !head[v])
            {
                ans ++;
                head[v] = true;
                Q.push(Node(v,v+1,my.round+1));
            }
            if(p[u] > 0 && sum[v] > 0 && !head[v+1])
            {
                ans ++;
                head[v+1] = true;
                Q.push(Node(v+1,v+2,my.round+1));
            }
        }
        cout<<ans<<endl;
    }
    View Code

    369E - Valera and Queries

    一直没思路,后来看题解知道要有求答案补集,因为正着来区间重复计数很难避免,而反着就是求不与点相交的区间的个数,进一步就是求每一个询问相邻点中区间的个数

    用树状数组计数就行

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define SHOW(x) { cerr << ">>> " << #x << " = " << x << endl; }
    
    using namespace std;
    
    const int maxn = 1e6+10;
    const int MV = 1e6+1;
    
    struct BIT
    {
        int C[maxn];
    
        int lowbit(int x)
        {
            return x&(-x);
        }
    
        void init()
        {
            memset(C,0,sizeof(C));
        }
    
        void add(int x,int a)
        {
            while(x <= MV)
            {
                C[x] += a;
                x += lowbit(x);
            }
        }
    
        int sum(int x)
        {
            if(x == 0) return 0;
            int ret = 0;
            while(x > 0)
            {
                ret += C[x];
                x -= lowbit(x);
            }
            return ret;
        }
    }bit;
    //要求一个区间内的线段的个数
    
    struct Node
    {
        int l,r;
        int id;
        bool operator < (const Node& rhs) const
        {
            return r < rhs.r;
        }
    }I[maxn/3],Q[2*maxn/3];   //就由于一个数组开错了啊
    int ans[maxn/3];
    
    int main()
    {
        freopen("E:\acm\input.txt","r",stdin);
        int n,m;
        cin>>n>>m;  
        bit.init();
    
        for(int i=1; i<=n; i++)
        {
            scanf("%d %d",&I[i].l,&I[i].r);
        }
    
        int cnt = 0;
        for(int i=1; i<=m; i++)
        {
            int num;
            scanf("%d",&num);
            for(int j=1; j<=num; j++)
            {
                int p;
                scanf("%d",&p);
    
                Q[++cnt].id = i;
    
                if(j == 1)
                    Q[cnt].l = 0;
                else
                    Q[cnt].l = Q[cnt-1].r;
    
                Q[cnt].r = p;
            }
            Q[++cnt].id = i;
            Q[cnt].l = Q[cnt-1].r;
            Q[cnt].r = MV;
        }
        sort(I+1,I+n+1);
        sort(Q+1,Q+cnt+1);
    
        for(int i=1; i<=m; i++) ans[i] = n;
    
        int pv = 1;
        for(int i=1; i<=cnt; i++)
        {
            while(pv <= n && I[pv].r < Q[i].r)
            {
                bit.add(I[pv].l,1);
                pv++;
            }
            ans[Q[i].id] -= bit.sum(Q[i].r-1) - bit.sum(Q[i].l);
        }
        for(int i=1; i<=m; i++)
            printf("%d
    ",ans[i]);
    }
    View Code
  • 相关阅读:
    在 Anaconda下解决国内安装tensorflow等下载慢和中断,出错,异常问题的一点思路
    关于指针和结构体的一点教训
    ARM cortexM4中断优先级的一点理解。
    ubuntu16下的/etc/resolv.conf重置的解决方案
    linux安装dpkg安装缺少依赖项的解决
    莲藕的简单凉菜制作总结
    单片机一种简便的printf调试方案。
    usart下位机输出使用printf的格式化技巧
    关于xp操作系统下使用VC6++编写的上位机软件在win10中运行的问题
    百度面试两板斧:手写算法问基础
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3467809.html
Copyright © 2011-2022 走看看