题意就是给一个n个顶点的简单凸多边形,从第一个顶点出发向第k+1个顶点连一条线段,同时输出此时多边形被分割为几部分,接下来再从第k+1个点出发向k+1 + k 点 连 一条线段,再求此时被分割为几部分。(如果超过第n点,就再从第一个点开始)如此循环操作n次。输入中的 n k互质,从而保证该多边形每个顶点都会到过一次而且前n次不会重复到同一个点。
画一个图分析一下可以看出来,从一个点到另一个点连线产生的贡献,只和中间经过的点是否已经有了连线有关系,如图
(不知道为什么把图片转正了之后上传上来还是倒的,治好多年的颈椎病) 其实是和中间哪些点有连线和连线的数目有关系,由于每个点会有入度出度两条线(暂且这么叫吧),要注意不能经过这个点后马上给该点加上值。又是如图:
由于从某一个点出发往下一个点连线,不可能与上个点与该点连线相交叉。因此我们在到达下一个点时,再把值加给上一个点(如到达第三个点时,再给第一个点加上1, 同时给第6个点加1,到达下一个点时再给第6个点加上1,同时给第3个点加上1)
每一条连线产生的分隔贡献=上一条线的分隔数+【中间经过的所有点(不包括出发点和到达点)的值的和】+1
由于数字较大,我们用一个树状数组或者线段树来维护即可
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<time.h>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<iostream>
using namespace std;
#define LONG long long
const LONG INF=0x3f3f3f3f;
const LONG MOD=1e9+7;
const double PI=acos(-1.0);
#define clrI(x) memset(x,-1,sizeof(x))
#define clr0(x) memset(x,0,sizeof x)
#define clr1(x) memset(x,INF,sizeof x)
#define clr2(x) memset(x,-INF,sizeof x)
#define EPS 1e-10
LONG ans[1000100];
LONG tree[1000100];
LONG n;
LONG lowbit(LONG x)
{
return x & ( -x);
}
void add(LONG x,LONG val)
{
while(x<=n)
{
tree[x] +=val;
x +=lowbit(x);
}
}
LONG sum(LONG x)
{
LONG tot = 0;
while(x>0)
{
tot += tree[x];
x -= lowbit(x);
}
return tot ;
}
int main()
{
LONG k;
cin>>n>>k;
clr0(num);
clr0(tree);
num[1] = 1;
ans[1] = 2;
LONG pre = 1 + k;
LONG pree = 1;
for(LONG i = 2; i<=n ;++ i)
{
ans[i] = ans[i-1] + 1;
LONG now = pre + k;
// cout<<now<<endl;
if(now > n)
{
LONG res1= 0 , res2 = 0;
LONG tmp1 = sum( now - n -1 ) ;
LONG tmp2 = sum( n) - sum(pre );
res1 += tmp1;
res1 += tmp2 ;
res2 = sum( pre - 1) - sum( now - n );
ans[i] += min(res1 , res2);
now -= n;
add(pree , 1);
add(pre , 1);
pree = pre ;
pre = now ;
}
else
{
LONG res1= 0 , res2 = 0;
LONG tmp1 = sum( pre -1 ) ;
LONG tmp2 = sum( n) - sum( now );
res1 += tmp1;
res1 += tmp2 ;
res2 = sum( now -1 ) - sum( pre );
ans[i] +=min(res1 , res2);
add(pre, 1);
add(pree, 1);
pree = pre;
pre = now ;
}
}
for(LONG i = 1; i< n ;++ i)printf("%lld ",ans[i]);
cout<<ans[n]<<endl;
}