码迷,mamicode.com
首页 > 其他好文 > 详细

【GMOJ4018】Magic

时间:2020-02-10 17:50:28      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:src   tps   技术   图形   name   long   lin   add   个数   

题目

题目链接:https://gmoj.net/senior/#main/show/4018
一个环上有标号为\(1\)\(2n\)的顶点,每个顶点连接一条无向边。要求选择\(3\)条不重复的边在顶点处建熊洞(共\(6\)个),且每条边的两个顶点的距离相同,询问其方案数。
距离定义为在环上从一个顶点到另一个顶点所经过的最少熊洞数量-1。

思路

\(3\)条弦在一个圆中的相交情况只有如下五种:
技术图片
我们发现,满足题目要求的只有2号和5号。而这两种图形的方案都不是很好计算,所以考虑计算出不满足题目条件的图形个数。
假设我们先求出了\(l[i],r[i]\)表示第\(i\)条弦的左右分别有多少条与它不相交的弦,那么图1的情况就有\(\sum^{n}_{i=1}l[i]\times r[i]\)种,而图3和图4都有共同点:3条弦中都有两条弦满足另外两条线分别于它相交和相离,所以方案数就是\(\frac{(l[i]+r[i])\times (n-l[i]-r[i]-1)}{2}\).
那么现在的问题就是如何求\(l[i],r[i]\),容易发现,一条弦在另一条弦的左/右边,其实就是判断这两条线所连接的点的大小,分类讨论+二维偏序即可。
时间复杂度\(O(n\log n)\)

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

const int N=100010;
int n,l[N],r[N];
ll ans;

struct node
{
    int x,y,id;
}a[N];

struct BIT
{
    int c[N*2];
    
    void add(int x,int val)
    {
        for (;x<=n*2;x+=x&-x)
            c[x]+=val;
    }
    
    int ask(int x)
    {
        int sum=0;
        for (;x;x-=x&-x)
            sum+=c[x];
        return sum;
    }
}bit;

bool cmp1(node x,node y)
{
    return x.x<y.x;
}

bool cmp2(node x,node y)
{
    return x.y>y.y;
}

int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y);
        if (a[i].x>a[i].y) swap(a[i].x,a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+1+n,cmp1);
    for (int i=1;i<=n;i++)
    {
        l[a[i].id]+=bit.ask(a[i].x)+bit.ask(n*2)-bit.ask(a[i].y);
        bit.add(a[i].y,1);
    }
    memset(bit.c,0,sizeof(bit.c));
    for (int i=n;i>=1;i--)
    {
        r[a[i].id]+=bit.ask(a[i].y)-bit.ask(a[i].x);
        bit.add(a[i].y,1);
    }
    memset(bit.c,0,sizeof(bit.c));
    sort(a+1,a+1+n,cmp2);
    for (int i=1;i<=n;i++)
    {
        l[a[i].id]+=bit.ask(n*2)-bit.ask(a[i].y);
        bit.add(a[i].x,1);
    }
    ans=1LL*n*(n-1)*(n-2)/6;
    for (int i=1;i<=n;i++)
        ans-=(1LL*l[i]*r[i]+1LL*(l[i]+r[i])*(n-l[i]-r[i]-1)/2);
    printf("%lld",ans);
    return 0;
}

【GMOJ4018】Magic

标签:src   tps   技术   图形   name   long   lin   add   个数   

原文地址:https://www.cnblogs.com/stoorz/p/12291487.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!