传送门

显然题目问的那坨东西能转化成有多少点集的子集能圈出一个非退化的凸包(即面积大于$0$),所以把多点共线的情况减掉就行了。枚举直线上的第一个点和第二个点,统计出有多少点在这条线上,然后随便乘一乘加一加减一减就行了。注意不要把同一条直线算重复了。

#include <cstdio>
#include <cstring>
#define MAXN 210
#define LL long long

const LL P=998244353;

LL getPow(LL x,LL y){
    LL res=1;
    while(y){
        if(y&1) res=res*x%P;
        x=x*x%P;
        y>>=1;
    }
    return res;
}

struct vec2{
    int x,y;
    vec2(int _x=0,int _y=0):x(_x),y(_y){}
    friend vec2 operator-(vec2 x,vec2 y){ return vec2(x.x-y.x,x.y-y.y); }
    friend int dot(vec2 x,vec2 y){ return x.x*y.x+x.y*y.y; }
    friend int cross(vec2 x,vec2 y){ return x.x*y.y-x.y*y.x; }
}p[MAXN];

int n;

int main(){
#ifdef DEBUG
    freopen("E.in","r",stdin);
#endif
    LL inv2=getPow(2,P-2);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);
    LL ans=getPow(2,n);
    LL res=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i^j){
                vec2 d=p[j]-p[i];
                int cnt=2;
                for(int k=1;k<=n;k++)
                    if(cross(p[k]-p[j],d)==0 && k!=i && k!=j){
                        if(dot(p[k]-p[j],d)<0){
                            cnt=0;
                            break;
                        }
                        cnt++;
                    }
                LL temp=getPow(2,cnt)-cnt-1;
                res=(res+temp)%P;
            }
    res=res*inv2%P;
    res=(res+n+1)%P;
    ans-=res;
    ans=(ans%P+P)%P;
    printf("%lld\n",ans);
}