zoukankan      html  css  js  c++  java
  • 【AUOJ1587】矿石

    题面

    众所周知,温爷家里有矿。

    你可以把温爷家的矿场抽象成一条数轴。温爷家有 n 种矿,第 i 种矿可以从 [li,ri] 中的任意位置开采得到。

    这个暑假, 地理老师给了温爷一个列表:温爷的暑假作业就是收集齐这些矿石。为了保证温爷的安全,温爷的爸爸选定了 m 个相对安全的采矿点,第 i 个采矿点的坐标为 ai。温爷只能选择其中一个采矿点开采他需要的矿石。

    温爷是一个马虎的♂男(nv)孩子。暑假刚开始没多久,温爷就把老师的列表弄丢了。唯一的线索是,列表上的所有矿石都是温爷家有的:一共有 2n−1 种可能的列表。

    温爷现在想要知道,在所有的可能的任务列表中,有多少种是他能够在某一个安全的采矿点完全收集齐的。

    对于 20% 的数据,n,m≤20.

    对于 40% 的数据,n≤20.

    对于 60% 的数据,n,m≤1000.

    对于 100% 的数据 , n,m≤1e5,1≤li,ri,ai≤1e9,保证 ai 两两不同

    分析

    气死我了!!!忽略了bitset的count的效率是O(N)的,以为写得满分算法,结果挂了...

    将左右端点和采矿点都加进来排序离散化。

    主要问题在于如何判重,我用bitset可以直接判断两个采矿点的贡献区间的交

    显然的结论 ans+=2dif * (2same-1) 其中dif是两集合不重复的,same是重复的,需要用bitset的count来计算,这是60分做法

    满分做法只需要每次多维护俩int,分别记录与前一个相交的数量以及现在有贡献的新区间数量。

    遇到一个左端点,就使新加区间+1,遇到一个右端点,如果是在上一次标记过的,就使相交区间减一,否则使新区间数减一。

    代码

    60pts

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100010
    #define ll long long
    #define mod 998244353
    ll n,m,pl,nl,cnt,ans,tmp,flag;
    struct email
    {
        ll v,c,id;
    }a[N*4];
    bitset<N>now,pre,same;
    bool cmp(email x,email y)
    {
        if(x.v==y.v)
            return x.c>y.c;
        return x.v<y.v;
    }
    inline void read(ll &x)
    {
        x=0;char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    }
    
    inline ll ksm(ll a,ll b)
    {
        ll ret=1;
        while(b)
        {
            if(b&1)ret=(ret*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ret;
    }
    
    int main()
    {
        read(n),read(m);
        for(ll i=1;i<=n;i++)
        {
            ll l,r;
            read(l),read(r);
            a[++cnt].v=l;a[cnt].c=2;a[cnt].id=i;
            a[++cnt].v=r;a[cnt].c=0;a[cnt].id=i;
        }    
        for(ll i=1;i<=m;i++)
        {
            ll x;
            read(x);
            a[++cnt].v=x;a[cnt].c=1;
        }
        sort(a+1,a+1+cnt,cmp);
        ll i=1;
        for(ll i=1;i<=cnt;i++)
        {
            if(a[i].c==2){tmp++;now[a[i].id]=1;}
            if(a[i].c==0){tmp--;now[a[i].id]=0;}
            if(a[i].c==1)
            {
                if(flag==0)
                {
                    ans=ksm(2,tmp)-1;
                    flag=1;pre=now;
                }
                same=pre&now;
                if(same==now){continue;}
                else
                {
                    pl=same.count();nl=now.count()-same.count();
                    ans=(ans+(ksm(2,pl)*(ksm(2,nl)-1)%mod))%mod;
                    pre=now;
                }
            }    
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
                        


    100pts

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100010
    #define ll long long
    #define mod 998244353
    ll n,m,pl,nl,cnt,ans,tmp,flag,p,q;
    struct email
    {
        ll v,c,id;
    }a[N*4];
    bitset<N>now;
    bool cmp(email x,email y)
    {
        if(x.v==y.v)
            return x.c>y.c;
        return x.v<y.v;
    }
    inline void read(ll &x)
    {
        x=0;char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    }
    
    inline ll ksm(ll a,ll b)
    {
        ll ret=1;
        while(b)
        {
            if(b&1)ret=(ret*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ret;
    }
    
    int main()
    {
        read(n),read(m);
        for(ll i=1;i<=n;i++)
        {
            ll l,r;
            read(l),read(r);
            a[++cnt].v=l;a[cnt].c=2;a[cnt].id=i;
            a[++cnt].v=r;a[cnt].c=0;a[cnt].id=i;
        }    
        for(ll i=1;i<=m;i++)
        {
            ll x;
            read(x);
            a[++cnt].v=x;a[cnt].c=1;
        }
        sort(a+1,a+1+cnt,cmp);
        for(int i=1;i<=cnt;i++)
        {
            if(a[i].c==2){nl++;now[a[i].id]=1;}
            if(a[i].c==0)
            {
                if(now[a[i].id])now[a[i].id]=0,nl--;
                else pl--;
            }
            if(a[i].c==1)
            {
                ans=(ans+(ksm(2,pl)*(ksm(2,nl)-1)))%mod;
                pl+=nl;now=0;nl=0;
            }
        }
        printf("%lld
    ",ans);
        return 0;
        
    }
    
         
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    游标cursor
    SQL: EXISTS
    LeetCode Reverse Integer
    LeetCode Same Tree
    LeetCode Maximum Depth of Binary Tree
    LeetCode 3Sum Closest
    LeetCode Linked List Cycle
    LeetCode Best Time to Buy and Sell Stock II
    LeetCode Balanced Binary Tree
    LeetCode Validate Binary Search Tree
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9823318.html
Copyright © 2011-2022 走看看