【题解】Comet OJ 国庆欢乐赛 简要题解
【题解】Comet OJ 国庆欢乐赛 简要题解
A
直接做
B
直接做,结论:
\[ans=\max([Max\ge \mathrm{sum}] Max,s[n]/2)
\]
C
考虑这样一个做法:
对于一个左房子\((l,r)\),所有合法的右房子放在\(l-r\)坐标系上,合法的点是\((l',r')\)满足\(l'\le r \and r'\ge l\)的所有点。通过sort保证\(l'\le r\)合法,然后树状数组查询所有\(r'\ge l\)的个数。复杂度\(O(n\log M)\),要离散化
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=2e5+5;
int sav[maxn<<2];
int n,m,cnt,len;
#define l first
#define r second
pair<int,int> data[maxn],data2[maxn];
inline int arc(int x){return lower_bound(sav+1,sav+len+1,x)-sav;}
int seg[maxn<<2];
inline void add(const int&pos,const int&tag){
for(int t=pos;t<=len+1;t+=t&-t) seg[t]+=tag;
}
inline ll que(const int&pos){
int ret=0;
for(int t=pos;t>0;t-=t&-t) ret+=seg[t];
return ret;
}
int main(){
n=qr(); m=qr();
for(int t=1;t<=n;++t){
int t1=qr(),t2=qr();
data[t]={t1,t2};
sav[++*sav]=t1; sav[++*sav]=t2;
}
for(int t=1;t<=m;++t){
int t1=qr(),t2=qr();
data2[t]={t1,t2};
sav[++*sav]=t1; sav[++*sav]=t2;
}
sort(sav+1,sav+*sav+1);
len=unique(sav+1,sav+*sav+1)-sav-1;
for(int t=1;t<=n;++t) data[t].l=arc(data[t].l),data[t].r=arc(data[t].r);
for(int t=1;t<=m;++t) data2[t].l=arc(data2[t].l),data2[t].r=arc(data2[t].r);
sort(data+1,data+n+1);
sort(data2+1,data2+m+1);
ll ans=0;
for(int t=1,pos=0;t<=n;++t){
while(pos<m&&data2[pos+1].l<=data[t].r) add(data2[++pos].r,1);
ans+=pos-que(data[t].l-1);
}
printf("%lld\n",ans);
return 0;
}
博客保留所有权利,谢绝学步园、码迷等不在文首明显处显著标明转载来源的任何个人或组织进行转载!其他文明转载授权且欢迎!