zoukankan      html  css  js  c++  java
  • [arc082E]ConvexScore-[凸包]

    Description

    传送门

    Solution

    em又是神仙题。

    考虑到目前的一个凸包,顶点点集为S。

    现在在它内部或边缘上的点集为T,则贡献为2|T||S|,设从T中去掉S的点后得到了集合A。则2|T||S|=2|A|

    可知AUS的凸包点集还是S。

    好的关键点:A的子集个数为2|A|。怎么样是不是特别棒?

    设A'是A的子集,A'US的凸包点集还是为S,这样的A'也恰好有2|A|个,完美。

    所以,所有凸包点集为S的点集G,对答案的贡献都为1。

    然后注意这里要记得排除共线的情况。假如G中所有点都共线就无法形成凸包啦,减掉这些就OK。PS:空集也要减掉

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int mod=998244353;
    int n;
    ll pw[210],ans=0;
    struct node{int x,y;
    }p[210];
    bool check(node a,node b,node c)
    { return (b.x-a.x)*(c.y-a.y)==(b.y-a.y)*(c.x-a.x);}
    void link(int x,int y){x+=y;}
    int main()
    {
        link(0,1);
        scanf("%d",&n);
        pw[0]=1;
        for (int i=1;i<=n;i++) pw[i]=(pw[i-1]<<1)%mod;    
        for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);
        
        ans=(pw[n]-n-1+mod)%mod;bool _is;int cnt;
        for (int i=1;i<n;i++) 
            for (int j=i+1;j<=n;j++)
            {
                _is=1;
                for (int k=1;k<i;k++) if (check(p[k],p[i],p[j])) {_is=0;break;}
                for (int k=i+1;k<j;k++) if (check(p[k],p[i],p[j])) {_is=0;break;}
                if (!_is) continue;
                cnt=2;
                for (int k=j+1;k<=n;k++) if (check(p[k],p[i],p[j])) cnt++;
                ans=(ans-pw[cnt]+cnt+1+mod)%mod;
            }
        cout<<ans;
    }

     

  • 相关阅读:
    Running OOM killer script for process 32248 for Solr on port 8983
    List删除元素
    Oracle联合主键
    synchronized的四种用法
    数据库 乐观锁与悲观锁
    noip2011普及组 统计单词数
    bzoj3751 noip2014解方程
    汕头市队赛SRM07
    noip2010 导弹拦截&&vijos1810
    noip2009普及组 细胞分裂&&vijos1814
  • 原文地址:https://www.cnblogs.com/coco-night/p/9531857.html
Copyright © 2011-2022 走看看