zoukankan      html  css  js  c++  java
  • D

    题意:贴海报
    有一面很长的墙,大概有10000000 这么长,现有有一些海报会贴在墙上,当然贴海报的顺序是有先后的,问你当最后一张海报也贴上的时候能不能求出来在这面墙上能看到多少张不同的海报?
    分析:因为后面贴的海报会把前面贴的覆盖掉,不太容易求出来,但是如果从最后一张倒着贴,只要判断墙上这段区间有没有被完全覆盖就可以了,因为墙比较长,所以需要离散化一下。

    ************************************************************************
    注意:在向上跟新的时候返回值要在更新的下面要不直接返回了怎么更新??
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;

    const int maxn = 40005;

    int Hash[maxn];//记录离散化后的数据
    struct Post{int l, r;}p[maxn];//记录海报
    struct Tree
    {
        int L, R;
        bool isCover;//记录这段区间是否被覆盖
        int Mid(){return (L+R)/2;}
    }tree[maxn*4];

    void Up(int root)//向上更新,如果左右子树都被覆盖,那么他也会被覆盖
    {
        if(tree[root].L != tree[root].R)
        if(tree[root<<1].isCover && tree[root<<1|1].isCover)
            tree[root].isCover = true;
    }
    void Build(int root, int L, int R)
    {
        tree[root].L = L, tree[root].R = R;
        tree[root].isCover = false;

        if(L == R)return ;

        Build(root<<1, L, tree[root].Mid());
        Build(root<<1|1, tree[root].Mid()+1, R);
    }
    //如果区间能内还有位置返回真,否则返回假
    bool Insert(int root, int L, int R)
    {
        if(tree[root].isCover)return false;

        if(tree[root].L == L && tree[root].R == R)
        {
            tree[root].isCover = true;
            return true;
        }
        
        bool ans;

        if(R <= tree[root].Mid())
            ans =  Insert(root<<1, L, R);
        else if(L > tree[root].Mid())
            ans =  Insert(root<<1|1, L, R);
        else
        {
            bool Lson = Insert(root<<1, L, tree[root].Mid());
            bool Rson = Insert(root<<1|1, tree[root].Mid()+1, R);

            ans = Lson | Rson;
        }

        Up(root);

        return ans;
    }

    int main()
    {
        int T;

        scanf("%d", &T);

        while(T--)
        {
            int i, N, nh=0;

            scanf("%d", &N);

            for(i=1; i<=N; i++)
            {
                scanf("%d%d", &p[i].l, &p[i].r);
                Hash[nh++] = p[i].l, Hash[nh++] = p[i].l-1;
                Hash[nh++] = p[i].r, Hash[nh++] = p[i].r+1;
            }
            sort(Hash, Hash+nh);
            nh = unique(Hash, Hash+nh) - Hash;

            Build(11, nh);

            int ans = 0;

            for(i=N; i>0; i--)
            {
                int l = lower_bound(Hash, Hash+nh, p[i].l) - Hash;
                int r = lower_bound(Hash, Hash+nh, p[i].r) - Hash;

                if(Insert(1, l, r) == true)
                    ans += 1;
            }

            printf("%d ", ans);
        }

        return 0;
    }
  • 相关阅读:
    WCF中关于可靠会话的BUG!!
    控制并发访问的三道屏障: WCF限流(Throttling)体系探秘[下篇]
    《天使之恋》,一部重口味的纯美爱情电影
    一个关于解决序列化问题的编程技巧
    [转]Design Rules for ModelViewPresenter
    你知道Unity IoC Container是如何创建对象的吗?
    只在UnitTest和WebHost中的出现的关于LogicalCallContext的严重问题
    使命必达: 深入剖析WCF的可靠会话[原理揭秘篇](上)
    回调与并发: 通过实例剖析WCF基于ConcurrencyMode.Reentrant模式下的并发控制机制
    如何编写没有Try/Catch的程序
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4678083.html
Copyright © 2011-2022 走看看