2024.11.19 模拟赛
11.19 模拟赛
题目质量点赞!好题!
storm
普及组模拟题
god
有趣的 dp 题
key:考察相对位置设计状态
\(f(i,j)\) 表示考虑后 \(i\) 个操作,经过了相对坐标为 \(j\) 的点的概率。
转移中,如果这一步不动,相对坐标不变;否则,相对坐标整体平移。
答案就是 \(f(n,j)\)。
fate
瞎搞贪心题
显然从左到右依次考虑能否放左括号,关键在于判定“同组”的是否合法。
场上用线段树维护后缀和,按照括号匹配的一般思路,要求后缀和最大值不大于 0。
常数较大,卡了一会才过。
题解是一个结论:
合法括号匹配的左括号序列被 \(1,3,5,\dots,2n-1\) 偏序
故考虑给每个左括号匹配一个值,set 维护当前还未匹配的值,每次查询能否匹配即可。
rectangle
容斥 + 扫描线 码力题
将每个矩形看作一个点,有交的矩形之间连边,问题转化为求有多少个 \((i,j,k)\) 的生成子图没有边。
考虑容斥,用所有三元组的数量减去有边的三元组的数量。记有 \(1\) 条边的个数为 \(c_1\),\(2\) 条边的个数为 \(c_2\),\(3\) 条边的个数为 \(c_3\),答案为 \({n \choose 3} - c_1 -c_2 -c_3\)。
step1:用度数 \(d_i\) 求出 \(c_1+c_2\)
- 至少有一条边时(选一个点 \(i\),再选一个与 \(i\) 相连的点 \(j\),再随便选一个点 \(k\)):\(\sum d_i(n-2)=2c_1+4c_2+6c_3\)
- 至少有两条边时(选一个点 \(i\),再选两个与 \(i\) 相连的点 \(j,k\) ):\(\sum {d_i \choose 2} =c_2+3c_3\)
step2:扫描线求出 \(d_i\)
考虑正常的从左往右扫,此时可以保证横向全都有交,只需考虑纵向。
\((a,b)\) 纵向有交 当且仅当 \(yl_b\le yr_a\) 且 \(yr_b \ge yl_a\)(已知两两不同)
故用 \(\le yr_a\) 的 \(yl\) 数量减去 $< yl_a $ 的 \(yr\) 数量,最后再减掉自己即可。
横向扫描线就是对 \(xl\le xr_a\) 和 \(xr<xl_a\) 分别计算,保证横向有交。
step3:容斥求出 \(c_3\)
考虑在 \(xl\) 最大的位置统计三元组,不妨为 \(i\)。
从与 \(i\) 有交的点中选 \(j,k\),再减去 \(j,k\) 不交的情况。
发现此时 \(xl_j\le xl_i\le xr_j\) 且 \(xl_k\le xl_i\le xr_k\),即 \(j,k\) 横向必有交,故只需考虑纵向。
不妨令 \(yr_j<yl_k\),则必有 \(yl_i\le yr_j<yl_k\le yr_i\),可以用线段树维护。
附:线段树维护信息
\((a,b,c)\) 表示区间内有 \(a\) 个 \(yr\),\(b\) 个 \(yl\),\(c\) 对 \(yr<yl\)
合并时 \(a,b\) 直接相加,\(c\) 要加上左边的 \(a\) 乘右边的 \(b\)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define per(i,x,y) for(int i=x;i>=y;i--)
#define REPG(i,g,x) for(int i=g.head[x];~i;i=g.edge[i].nxt)
#define LL long long
template<class T>
inline void read(T &x){
T s=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) s=s*10+c-'0';
x=s*f;
}
const int N=4e5+5;
inline LL c2(LL x){
return x*(x-1)/2;
}
inline LL c3(LL x){
return x*(x-1)*(x-2)/6;
}
int limx,limy;
struct bit{
int c[N];
inline void upd(int x,int v){
for(int i=x;i<=limy;i+=(i&-i)) c[i]+=v;
}
inline int ask(int x){
int res=0;
for(int i=x;i;i-=(i&-i)) res+=c[i];
return res;
}
inline int que(int l,int r){
return ask(r)-ask(l-1);
}
}xlyl,xlyr,xryl,xryr,nwyl,nwyr;
namespace seg{
struct info{
LL a,b,c;
info(LL a=0,LL b=0,LL c=0):a(a),b(b),c(c){}
inline info operator+(const info &x)const{
return info(a+x.a,b+x.b,c+x.c+x.a*b);
}
}ino[2*N];
int tot;
int ls[2*N],rs[2*N];
inline void pushup(int x){
ino[x]=ino[ls[x]]+ino[rs[x]];
}
inline int build(int l,int r){
int x=++tot;
if(l==r) return ino[x]=info(0,0,0),x;
int mid=(l+r)>>1;
ls[x]=build(l,mid);
rs[x]=build(mid+1,r);
return pushup(x),x;
}
inline void upda(int x,int l,int r,int p,int v){
if(l==r) return ino[x].a+=v,void();
int mid=(l+r)>>1;
if(p<=mid) upda(ls[x],l,mid,p,v);
else upda(rs[x],mid+1,r,p,v);
return pushup(x);
}
inline void updb(int x,int l,int r,int p,int v){
if(l==r) return ino[x].b+=v,void();
int mid=(l+r)>>1;
if(p<=mid) updb(ls[x],l,mid,p,v);
else updb(rs[x],mid+1,r,p,v);
return pushup(x);
}
inline info ask(int x,int l,int r,int s,int t){
if(l>=s && r<=t) return ino[x];
int mid=(l+r)>>1;info res(0,0,0);
if(s<=mid) res=res+ask(ls[x],l,mid,s,t);
if(t>mid) res=res+ask(rs[x],mid+1,r,s,t);
return res;
}
}
int n;
struct rec{
int xl,xr,yl,yr,du;
}r[N];
int cx[N],cy[N];
int opt[N];
int main(){
read(n);
rep(i,1,n){
read(r[i].xl),read(r[i].xr),read(r[i].yl),read(r[i].yr);
cx[2*i-1]=r[i].xl,cx[2*i]=r[i].xr;
cy[2*i-1]=r[i].yl,cy[2*i]=r[i].yr;
}
limx=limy=2*n;
sort(cx+1,cx+2*n+1);sort(cy+1,cy+2*n+1);
rep(i,1,n){
r[i].xl=lower_bound(cx+1,cx+limx+1,r[i].xl)-cx;
r[i].xr=lower_bound(cx+1,cx+limx+1,r[i].xr)-cx;
r[i].yl=lower_bound(cy+1,cy+limy+1,r[i].yl)-cy;
r[i].yr=lower_bound(cy+1,cy+limy+1,r[i].yr)-cy;
}
rep(i,1,n) opt[r[i].xl]=i,opt[r[i].xr]=-i;
seg::build(1,limy);
LL res3=0;
rep(x,1,limx){
int i=opt[x];
if(i<0){
i=-i;
xryl.upd(r[i].yl,1);
xryr.upd(r[i].yr,1);
nwyl.upd(r[i].yl,-1);
nwyr.upd(r[i].yr,-1);
seg::upda(1,1,limy,r[i].yl,-1);
seg::updb(1,1,limy,r[i].yr,-1);
r[i].du+=xlyl.ask(r[i].yr)-xlyr.ask(r[i].yl-1)-1;
}else{
xlyl.upd(r[i].yl,1);
xlyr.upd(r[i].yr,1);
r[i].du-=xryl.ask(r[i].yr)-xryr.ask(r[i].yl-1);
res3+=c2(nwyl.ask(r[i].yr)-nwyr.ask(r[i].yl-1))-seg::ask(1,1,limy,r[i].yl,r[i].yr).c;
nwyl.upd(r[i].yl,1);
nwyr.upd(r[i].yr,1);
seg::upda(1,1,limy,r[i].yl,1);
seg::updb(1,1,limy,r[i].yr,1);
}
}
LL all=c3(n),res12=0;
rep(i,1,n) res12+=1ll*(n-2)*r[i].du-2*c2(r[i].du);
res12/=2;
printf("%lld\n",all-res12-res3);
return 0;
}

浙公网安备 33010602011771号