[离散化][二分]JZOJ 5892 矿石

Description
 
Input
Output
 
Sample Input
3 2
7 11
1 5
3 8
4
7
Sample Output
5
 
Data Constraint

分析

x为该点可以采的矿石种类量

一个点的方案数为2^k-1

那么当前点可以采的矿石种类量和之前的重叠了y中,而没有重叠的为z种

方案数则为(2^y)*(2^z -1)

然后我们给点的位置离散化,在里面二分找l,r的位置,然后记录到前缀和数组里就行了

 

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const ll P=998244353;
ll pow[N];
ll dif[N],sam[N];
ll l[N],r[N],a[N];
int n,m;

int main() {
    freopen("ore.in","r",stdin);
    freopen("ore.out","w",stdout);
    scanf("%d%d",&n,&m);
    pow[0]=1ll;
    for (int i=1;i<=n;i++) pow[i]=pow[i-1]*2ll%P;
    for (int i=1;i<=n;i++) scanf("%lld%lld",&l[i],&r[i]);
    for (int i=1;i<=m;i++) scanf("%lld",&a[i]);
    sort(a+1,a+m+1);
    for (int i=1;i<=n;i++) {
        int fir=lower_bound(a+1,a+m+1,l[i])-a,
        las=upper_bound(a+1,a+m+1,r[i])-a;
        if (a[fir]<=r[i]) dif[fir]++;
        if (fir<las) sam[fir+1]++,sam[las]--;
    }
    ll ans=0;
    for (int i=1;i<=m;i++) {
        (sam[i]+=sam[i-1])%=P;
        (ans+=(pow[dif[i]]-1ll)*pow[sam[i]]%P)%=P;
    }
    printf("%lld",ans);
    fclose(stdin);fclose(stdout);
}
View Code

 

转载于:https://www.cnblogs.com/mastervan/p/9787867.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值