ZROI2018提高day3t2
分析
我们设A[i]表示点i有几个矿,B[i]表示这之中有几个矿是第一次出现,所以点i的贡献即为
(2^B[i]-1)*(2^(A[i]-B[i]))
注意减一的原因是第一次出现的矿应至少有一个。然后我们用set维护一下就可以了。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const long long mod = 998244353;
struct node {
long long x,y;
};
node d[500100];
set<long long>s;
inline bool cmp(const node a,const node b){
if(a.x==b.x)return a.y>b.y;
return a.x<b.x;
}
long long pw2[500100];
int main(){
long long n,m,sum=0,ans=0,i,j,k,cnt=0;
scanf("%lld%lld",&n,&m);
pw2[0]=1;
for(i=1;i<=n;i++)pw2[i]=pw2[i-1]*2%mod;
for(i=1;i<=n;i++){
long long x,y;
scanf("%lld%lld",&x,&y);
d[++cnt].x=x,d[cnt].y=i;
d[++cnt].x=y,d[cnt].y=-i;
}
for(i=1;i<=m;i++){
long long x;
scanf("%lld",&x);
d[++cnt].x=x;
}
sort(d+1,d+cnt+1,cmp);
for(i=1;i<=cnt;i++){
if(!d[i].y){
ans=(ans+(pw2[s.size()]-1)*pw2[sum-s.size()]%mod)%mod;
s.clear();
}
if(d[i].y>0)s.insert(d[i].y),sum++;
if(d[i].y<0)s.erase(-d[i].y),sum--;
}
printf("%lld\n",ans);
return 0;
}