求助
  • 板块学术版
  • 楼主_lqs_
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/4/28 13:36
  • 上次更新2023/10/23 17:22:36
查看原帖
求助
664744
_lqs_楼主2023/4/28 13:36
二维坐标系里有n个点,第i个点的坐标是(x[i],y[i])。

所有的x[i]互异,所有的y[i]互异。

设P是这n个点的某个子集,maxX是该子集的x的最大值,minX是该子集的x的最小值,

maxY是该子集的y的最大值,minY是该子集的y的最小值。

显然(maxX, minX, maxY, minY)确定了一个矩形,我们不妨假设该矩形内部(含边界)共有k个点,

我们定义点集P的价值f(P) = k。

对于所有不同的点集p,输出f(p)累加的和,答案模998244353。

输入格式
第一行,一个整数n。 1<=n<=200000。

接下来有n行,第i行是x[i]和y[i],  -1e9<=x[i],y[i]<=1e9。

输出格式
一个整数。

输入/输出例子1
输入:

3

-1 3

2 1

3 -2



输出:

13



输入/输出例子2
输入:

4

1 4

2 1

3 3

4 2



输出:

34



输入/输出例子3
输入:

10

19 -11

-3 -12

5 3

3 -15

8 -14

-9 -20

10 -9

0 2

-7 17

6 -6



输出:

7222

站外题,写了四颗树状数组但是样例 33 过不了,不知道哪里出了问题。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lowbit(x) x&(-x) 
#define N 200005
const int mod=998244353;
//2^-1=2^(mod-2)
int n,m,i,j,ans,k,x;
int t1[N<<1],t2[N<<1],t3[N<<1],t4[N<<1],qpow[N<<1];
int cnt1[N],cnt2[N],cnt3[N],cnt4[N],num[N<<1];
struct ren{
	int a,b,id;
}d[N];
bool cmp1(ren x,ren y){
	if(x.a!=y.a) return x.a<y.a;
	return x.b>y.b;
}//左上 
bool cmp2(ren x,ren y){
	if(x.a!=y.a) return x.a>y.a;
	return x.b>y.b;
}//右上 
bool cmp3(ren x,ren y){
	if(x.a!=y.a) return x.a<y.a;
	return x.b<y.b;
}//左下 
bool cmp4(ren x,ren y){
	if(x.a!=y.a) return x.a>y.a;
	return x.b<y.b;
}//右下 
int q1(int x){
	int sum=0;
	for(;x>=1;x-=lowbit(x)) sum+=t1[x];
	return sum;
}
int u1(int x,int k){
	for(;x<=(n*2);x+=lowbit(x)) t1[x]+=k;
}
int q2(int x){
	int sum=0;
	for(;x>=1;x-=lowbit(x)) sum+=t2[x];
	return sum;
}
int u2(int x,int k){
	for(;x<=(n*2);x+=lowbit(x)) t2[x]+=k;
}
int q3(int x){
	int sum=0;
	for(;x>=1;x-=lowbit(x)) sum+=t3[x];
	return sum;
}
int u3(int x,int k){
	for(;x<=(n*2);x+=lowbit(x)) t3[x]+=k;
}
int q4(int x){
	int sum=0;
	for(;x>=1;x-=lowbit(x)) sum+=t4[x];
	return sum;
}
int u4(int x,int k){
	for(;x<=(n*2);x+=lowbit(x)) t4[x]+=k;
}
signed main(){
	scanf("%lld",&n);
	qpow[0]=1;for(i=1;i<=n*2;i++) qpow[i]=qpow[i-1]*2%mod;
	for(i=1;i<=n;i++){
		scanf("%lld%lld",&d[i].a,&d[i].b);
		num[++k]=d[i].a,num[++k]=d[i].b;
		d[i].id=i;
	} 
	sort(num+1,num+k+1);
	k=unique(num+1,num+k+1)-num-1;
	for(i=1;i<=n;i++){
		d[i].a=lower_bound(num+1,num+k+1,d[i].a)-num;
		d[i].b=lower_bound(num+1,num+k+1,d[i].b)-num;
	}
	sort(d+1,d+1+n,cmp1);
	for(i=1;i<=n;i++){
		cnt1[d[i].id]=q1(n<<1)-q1(d[i].b-1);
		u1(d[i].b,1);
	}
	sort(d+1,d+1+n,cmp2);
	for(i=1;i<=n;i++){
		cnt2[d[i].id]=q2(n<<1)-q2(d[i].b-1);
		u2(d[i].b,1);
	}
	sort(d+1,d+1+n,cmp3);
	for(i=1;i<=n;i++){
		cnt3[d[i].id]=q3(d[i].b);
		u3(d[i].b,1);
	}
	sort(d+1,d+1+n,cmp4);
	for(i=1;i<=n;i++){
		cnt4[d[i].id]=q4(d[i].b);
		u4(d[i].b,1);
	}
	for(i=1;i<=n;i++){
		ans=(ans+qpow[cnt1[i]-1]%mod*qpow[cnt4[i]-1]%mod*qpow[cnt2[i]]%mod*qpow[cnt3[i]]%mod)%mod;
		ans=(ans+qpow[cnt2[i]-1]%mod*qpow[cnt3[i]-1]%mod*qpow[cnt1[i]]%mod*qpow[cnt4[i]]%mod)%mod;
		ans=(ans-qpow[cnt1[i]-1]%mod*qpow[cnt4[i]-1]%mod*qpow[cnt2[i]-1]%mod*qpow[cnt3[i]-1]%mod)%mod;
		ans=(ans+qpow[n-1])%mod;
	}
	printf("%lld\n",ans);
	return 0;
}

/*
以每个点构建直角坐标系
则有四个象限
包含原点条件有:
1.一、三象限必选一个,二、四象限随意;
2.二、四象限必选一个,一、三象限随意;
显然以上两种情况是有重复计算贡献的,也就是重复计算了四个象限都选的情况
所以是简单容斥
记四个象限点数分别为s1、s2、s3、s4
则对答案的贡献为:
2^(s1-1)*2^(s3-1)*2^s2*2^s4+2^(s2-1)*2^(s4-1)*2^s1*2^s3-2^(s1-1)*2^(s2-1)*2^(s3-1)*2^(s4-1)  
位于四个方位点的数量是二维偏序,用树状数组维护。 
对了,还要离散化 
*/
2023/4/28 13:36
加载中...