Codeforces 755-D. PolandBall and Polygon(树状数组+计算几何)

记录一个菜逼的成长。。

题目链接
题目大意:
给你一个凸n边形。从1开始,将点与接下来的第k个点连条线,然后从第k个点开始重复操作,每次操作输出凸边形有多少块区域。不会有三条线交于一点的情况。

我们需要知道每次连线相交了多少条线。
假设现在在x点,那么只需要知道x+1,…,x+k-1和x-k+1,…,x-1有多少条线是以这些点为起点的。因为如果是以这些点为起点的线,那么x’+k肯定会超过x或x+k。
但是k必须满足min(k,n-k)
因为如果k超过了n/2那么有些线段会被计算两次。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define pb push_back
#define mp make_pair
#define lowbit(x) (x)&(-x)
const int INF = 0x3f3f3f3f;
const int maxn = 1000000 + 10;
//tot是用来统计目前为止有多少条线段,也等于getsum(n)
int c[maxn],n,k,tot;
void modify(int pos,int t)
{
    for( int i = pos; i <= n; i += lowbit(i))
        c[i] += t;
    tot += t;
}
int getsum(int pos)
{
    int ret = 0;
    for( int i = pos; i >= 1; i -= lowbit(i))
        ret += c[i];
    return ret;
}
int query(int x)
{
    if(x >= n)return getsum(x-n) + tot;
    else if(x < 0)return getsum(x+n) - tot;
    return getsum(x);
}
int main()
{
    while(~scanf("%d%d",&n,&k)){
        k = min(k,n-k);
        LL ans = 1;int x = 1;
        for( int i = 1; i <= n;i++ ){
            int t = query(x+k-1) - query(x-k);
            ans += t + 1;
            modify(x,1);
            x = (x + k - 1) % n + 1;
            printf("%lld ",ans);
        }
        puts("");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值