codeforces 755D. PolandBall and Polygon

D. PolandBall and Polygon
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Input

There are only two numbers in the input: n and k (5 ≤ n ≤ 106, 2 ≤ k ≤ n - 2, gcd(n, k) = 1).

Output

You should print n values separated by spaces. The i-th value should represent number of polygon's sections after drawing first i lines.

Examples
input
5 2
output
2 3 5 8 11 
input
10 3
output
2 3 4 6 9 12 16 21 26 31 
Note

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.

codeforces 755D. PolandBall and Polygoncodeforces 755D. PolandBall and Polygoncodeforces 755D. PolandBall and Polygoncodeforces 755D. PolandBall and Polygoncodeforces 755D. PolandBall and Polygoncodeforces 755D. PolandBall and Polygon

题目大意:一个n边形,从1号点开始,每次走到(x+k-1)%n+1位置,问每次留下来的路径把这个多边形划分成了几个部分。
2 ≤ k ≤ n - 2, gcd(n, k) = 1,可以发现一定每个点一定经过一次,插入边的时候对应的点对应了一个区间,两条直线不相交(贡献答案)当且仅当他们的区间无交集,因为一个点只对应一个区间(只考虑出去的那个),用树状数组维护一下即可。

 有个细节:如果2k>n,那么把k转化一下为n-k就可以了。(以为这个细节很显然,然后就没去hack,结果本来房间里10个对的然后就只剩3个没fst,MDZZ)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define maxn 1000010
10 #define llg long long 
11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
12 llg n,m,cs[maxn],k,x,y,ans,c[maxn];
13 
14 llg lowbit(llg x) {return x&-x;}
15 void add(llg w,llg v)
16 {
17     while (w<=n)
18     {
19         c[w]+=v; w+=lowbit(w);
20     }
21 }
22 llg sum(llg w)
23 {
24     llg ans=0;
25     while (w>0)
26         {
27             ans+=c[w]; w-=lowbit(w);
28         }
29     return ans;
30 }
31 
32 llg work(llg x,llg y)
33 {
34     
35     llg l=y,r=y+n-k-k;
36     if (r>n)
37     {
38         r-=n;
39         return sum(n)-sum(l-1)+sum(r);
40     }
41     else return sum(r)-sum(l-1);
42 }
43 
44 int main()
45 {
46     yyj("D");
47     cin>>n>>k;
48     if (k>n/2) k=n-k;
49     x=1;
50     ans=1;// add(1,1);
51     for (llg i=1;i<=n;i++)
52     {
53         y=x+k;
54         if (y>n) y-=n;
55         ans+=i-work(x,y);
56         add(x,1);
57         x=y;
58         printf("%lld ",ans);
59     } 
60     return 0;
61 }