atcoderEnclosed Points [abc136F]

Posted quzhizhou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了atcoderEnclosed Points [abc136F]相关的知识,希望对你有一定的参考价值。

  题目传送门:https://atcoder.jp/contests/abc136/tasks/abc136_f

  题目大意:在平面上有$n$个点我们,定义一个点集的权值为平面上包含这个点集的最小矩形所包含的点个数(矩形的边与坐标轴平行),求所有非空点集的权值和,保证每个点的横纵坐标互不相同。

  先考虑转化一下,求每个点被多少个点集$S$的矩形包含,假设我们当前考虑的是点$i$,那么可以分成两种情况:$i \\in S$或$i \\notin S$。

    1. 对于$i \\in S$的情况,容易发现点$i$对所有包含$i$的点集有贡献,这里的贡献为$2^(n-1)$。

    2. 对于$i \\notin S$的情况,因为每个点的横纵坐标互不相同,所以点$i$把整个坐标系划分成了4个区域

技术图片

    那么若点集$S$的矩形包含点$i$,那么必存在$p,q \\in S,p \\in A,q \\in D$或$p \\in B,q \\in D$。

    设$A$区域中的点数量为$a$,$B$区域中的点数量为$b$,$C$区域中的点数量为$c$,$D$区域中的点数量为$d$,容斥可知这里的贡献为$(2^a-1)2^b2^c(2^d-1)+2^a(2^b-1)(2^c-1)2^d-(2^a-1)(2^b-1)(2^c-1)(2^d-1)$。

  计算每个区域的点数可以将点排序离散化后用树状数组维护,于是就可以在$O(n \\log n)$的时间复杂度下解决问题。

  代码:

技术图片
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ll long long
#define mod 998244353
#define maxn 200010
inline ll read()

    ll x=0; char c=getchar(),f=1;
    for(;c<0||9<c;c=getchar())if(c==-)f=-1;
    for(;0<=c&&c<=9;c=getchar())x=x*10+c-0;
    return x*f;

inline void write(ll x)

    static char buf[20],len; len=0;
    if(x<0)x=-x,putchar(-);
    for(;x;x/=10)buf[len++]=x%10+0;
    if(!len)putchar(0);
    else while(len)putchar(buf[--len]);

inline void writesp(ll x)write(x); putchar( );
inline void writeln(ll x)write(x); putchar(\\n);
struct Data
    int x,id;
num[maxn];
struct point
    int x,y,rk;
a[maxn];
int n;
bool cmp1(Data a,Data b)return a.x<b.x;
bool cmp2(point a,point b)return a.x<b.x;
inline ll power(ll a,ll b)

    ll ans=1;
    for(;b;b>>=1,a=a*a%mod)
        if(b&1)ans=ans*a%mod;
    return ans;

int bit1[maxn],bit2[maxn];
void add1(int x,int k)for(;x<=n;x+=x&(-x))bit1[x]+=k;
int getsum1(int x)int sum=0; for(;x;x-=x&(-x))sum+=bit1[x]; return sum;
void add2(int x,int k)for(;x<=n;x+=x&(-x))bit2[x]+=k;
int getsum2(int x)int sum=0; for(;x;x-=x&(-x))sum+=bit2[x]; return sum;
int main()

    n=read();
    for(int i=1;i<=n;i++)
        a[i].x=read(); a[i].y=read();
        num[i].x=a[i].y; num[i].id=i;
    
    std::sort(num+1,num+n+1,cmp1);
    for(int i=1;i<=n;i++)
        a[num[i].id].rk=i;
    std::sort(a+1,a+n+1,cmp2);
    for(int i=1;i<=n;i++)
        bit1[i]=0,bit2[i]=i&(-i);
    ll ans=0;
    for(int i=1;i<=n;i++)
        add2(a[i].rk,-1);
        int A=getsum1(a[i].rk),B=getsum1(n)-getsum1(a[i].rk),C=getsum2(a[i].rk),D=getsum2(n)-getsum2(a[i].rk);
        ll totA=power(2,A),totB=power(2,B),totC=power(2,C),totD=power(2,D);
        ans=(ans+(totA-1)*totB%mod*totC%mod*(totD-1))%mod;
        ans=(ans+totA*(totB-1)%mod*(totC-1)%mod*totD)%mod;
        ans=(ans-(totA-1)*(totB-1)%mod*(totC-1)%mod*(totD-1)%mod+mod)%mod;
        ans=(ans+power(2,n-1))%mod;
        add1(a[i].rk,1);
    
    writeln(ans);
    return 0;
abc136F

 

以上是关于atcoderEnclosed Points [abc136F]的主要内容,如果未能解决你的问题,请参考以下文章

Visible Lattice Points

hdu 5626 Clarke and points

149. Max Points on a Line

vue conf 2021 points

lintcode-medium-Max Points on a Line

#Leetcode# 149. Max Points on a Line