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); }