zoukankan      html  css  js  c++  java
  • 【atcoder】Enclosed Points [abc136F]

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

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

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

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

        2. 对于$i otin 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('
    ');}
    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
  • 相关阅读:
    内网穿透事件参考
    mysql的优化总结
    linux切换普通用户遇bash-4.1解决
    python爬虫匹配实现步骤
    restful设计参考
    php扩展安装
    python算术
    python 文件操作
    python生成器
    Spring框架的事务管理之基于AspectJ的XML方式(重点掌握)
  • 原文地址:https://www.cnblogs.com/quzhizhou/p/11300139.html
Copyright © 2011-2022 走看看