题意:一个点集S被认为是好的,当且仅当任意一个S的子集T,总存在一个x>=a的矩阵(a任意,矩形的宽度任意)H.使得 H和S的交集==T... 题意真的难懂
给n个点,问有多少个满足题意的点集S
思路:
|S|=1 显然成立
|S|=2 只要这两个点y不相同就成立
|S|=3 只要三个点的相对位置满足"<"三点的位置,就可以成立
|S|=4 对于任意的3个点,总有不构成"<"三点位置的情况
|S|>=4 无解
注意去重
#include<cstdio>
#include<vector>
#include<cmath>
#include<string>
#include<queue>
#include<set>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e6+6;
const int MOD=998244353;
template <class T>
bool sf(T &ret){ //Faster Input
char c; int sgn; T bit=0.1;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
if(c==' '||c=='\n'){ ret*=sgn; return 1; }
while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
ret*=sgn;
return 1;
}
int n;
struct node{
ll x,y;
}p[N];
bool cmp(node a,node b){
return a.x>b.x;
}
ll c[N];
ll sum(ll x){
ll ans=0;
for(int i=x;i;i-=i&(-i)) ans+=c[i],ans%=MOD;
return ans;
}
void update(ll x){
for(int i=x;i<=n;i+=i&(-i)) c[i]++;
}
map<ll,int> x;
map<ll,int> y;
map<ll,int> cnt;
int main(void){
sf(n);
set<ll> xx;
set<ll> yy;
for(int i=1;i<=n;i++){
sf(p[i].x),sf(p[i].y);
xx.insert(p[i].x);
yy.insert(p[i].y);
}
int t=0;
for(auto num:xx) x[num]=++t;
t=0;
for(auto num:yy) y[num]=++t;
for(int i=1;i<=n;i++) p[i].x=x[p[i].x],p[i].y=y[p[i].y];
sort(p+1,p+1+n,cmp);
ll ans=0;
ans+=n;
int tot=0;
ll now=1;
for(int i=1;i<=n;i++){
ans+=tot-cnt[p[i].y];
tot++;
cnt[p[i].y]++;
ans%=MOD;
// cout << << endl;
ans+=sum(p[i].y-1)*( sum(n)-sum(p[i].y) );
ans%=MOD;
if(p[i].x!=p[i+1].x)
for(;now<=i;now++) update(p[now].y);
}
printf("%lld\n",ans%MOD);
return 0;
}