PolandBall has such a convex polygon with n veritces that no three of its diagonals intersect at the same point. PolandBall decided to improve it and draw some red segments.
He chose a number k such that gcd(n, k) = 1. Vertices of the polygon are numbered from 1 to n in a clockwise way. PolandBall repeats the following process n times, starting from the vertex 1:
Assume you've ended last operation in vertex x (consider x = 1 if it is the first operation). Draw a new segment from vertex x to k-th next vertex in clockwise direction. This is a vertexx + k or x + k - n depending on which of these is a valid index of polygon's vertex.
Your task is to calculate number of polygon's sections after each drawing. A section is a clear area inside the polygon bounded with drawn diagonals or the polygon's sides.
There are only two numbers in the input: n and k (5 ≤ n ≤ 106, 2 ≤ k ≤ n - 2, gcd(n, k) = 1).
You should print n values separated by spaces. The i-th value should represent number of polygon's sections after drawing first i lines.
5 2
2 3 5 8 11
10 3
2 3 4 6 9 12 16 21 26 31
The greatest common divisor (gcd) of two integers a and b is the largest positive integer that divides both a and b without a remainder.
For the first sample testcase, you should output "2 3 5 8 11". Pictures below correspond to situations after drawing lines.






例如这一次起点是1,终点是3,增加的区域数也就是2顶点上连的边个数加一,直接暴力求之间所有边的和肯定会t,所以用树状数组维护,模拟求和
但最后wa在了test6上。。。
没想出来为什么,看了题解,发现好智障
当k>n/2时,起点和终点的跨过区域就是反向的,令k=n-k即可(可以联想一下圆,扇形圆心角大于180度时候的情况)
#include<stdio.h>
int bit[1000006],n,k;
int sum(int i)
{
int s=0;
while(i>0)
{
s+=bit[i];
i-=i&-i;
}
return s;
}
void add(int i,int x)
{
while(i<=n)
{
bit[i]+=x;
i+=i&-i;
}
return ;
}
int main()
{
int x,be,ne,j,i;
long long int ans;
scanf("%d %d",&n,&k);
if(k>(n/2))
k=n-k;
j=n;
be=1;
ans=1;
while(j--)
{
ne=be+k;
if(ne>n)
{
ne-=n;
ans+=(sum(n)-sum(be));
ans+=sum(ne-1);
ans++;
}
else
{
ans+=(sum(ne-1)-sum(be)+1);
}
add(be,1);
add(ne,1);
be=ne;
printf("%lld ",ans);
}
printf("\n");
return 0;
}