codeforces D. 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.


题目大意:一个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 }
时间: 2024-12-28 21:09:23

codeforces D. PolandBall and Polygon的相关文章

【树状数组】Codeforces Round #755 D. PolandBall and Polygon

http://codeforces.com/problemset/problem/755/D 每次新画一条对角线的时候,考虑其跨越了几条原有的对角线. 可以用树状数组区间修改点查询来维护多边形的顶点.答案每次增加 新对角线的左端点在多少个区间内+右端点在多少个区间内+1,每次把新画的对角线所覆盖的较小区间内部的每个点加1即可.注意,一定要是较小的区间,因为这样才能保证其左右端点不同时在区间内,不会重复统计. #include<cstdio> #include<algorithm>

CodeForces - 755B PolandBall and Game(博弈)

题意:A和B两人每人都熟悉一些单词.A先开始,每人说一个单词,单词不能与两人之前说过的所有单词重复,谁无话可说谁输.两人可能有共同会的单词. 分析:因为要让对方尽量无单词可说,所以每个人优先说的都是两人共同会的单词,假设两人共同会的单词数为common. A会的单词数为n,B会的单词数为m. 1.common若为偶数,则两人说完共同会的单词后,若n-common>m-common,则A赢. 2.common若为奇数,则两人说完共同会的单词后,若n-common>m-common-1,则A赢.

Codeforces 437E The Child and Polygon(区间DP)

题目链接:Codeforces 437E The Child and Polygon 题目大意:给出一个多边形,问说有多少种分割方法,将多边形分割为多个三角形. 解题思路:首先要理解向量叉积的性质,一开始将给出的点转换成顺时针,然后用区间dp计算.dp[i][j]表示从点i到点j可以有dp[i][j]种切割方法.然后点i和点j是否可以做为切割线,要经过判断,即在i和j中选择的话点k的话,点k要在i,j的逆时针方. #include <cstdio> #include <cstring&g

Codeforces 755C:PolandBall and Forest(并查集)

http://codeforces.com/problemset/problem/755/C 题意:该图是类似于树,给出n个点,接下来p[i]表示在树上离 i 距离最远的 id 是p[i],如果距离相等则p[i]是 id 较小的点. 思路:一开始没什么想法,画几分钟图发现不到什么东西,后来想着 i 和 p[i] 有关系,那么就代表 i 和 p[i] 是属于同一棵树,那么不就是并查集了嘛.抱着试一试的心态搞了一下居然过了. 1 #include <cstdio> 2 #include <c

Codeforces 755B:PolandBall and Game(map+思维)

http://codeforces.com/problemset/problem/755/B 题意:A可以喊出n个字符串,B可以喊出m个字符串,如果一个字符串之前被喊过,那么它再也不能喊了,A先喊,最后没得喊的输.问谁赢. 思路:用map判断A.B中字符串一样的个数,因为A可以先喊,然后B再喊,每个人可以喊的数量要减去cnt / 2(如果是奇数,A可以喊多一个),表示被对方喊了.如果最后n<=m则A输,否则A赢,等于的情况是因为A先喊,B再喊,到最后A会输. 1 #include <cstdi

Codeforces Round #421 (Div. 2)B Mister B and Angle in Polygon

题目: 这里 题意:给一个正n(n <= 100000)边形和一个角度a,在正n边形n找到3个不同的顶点v1,v2,v3,使得 和a之间的差最小,并且输出v1,v2,v3: 思路:可以把这个多边形放在一个圆里面.发现的大小等于v1,v3对应圆心角/2.所有的角都是180/a的倍数.固定一个点的位置1,然后以2为圆心角的起点为n-1的终点枚举另一个点的位置即可. 代码: // #include<bits/stdc++.h> using namespace std; const int ma

Codeforces 755 G. PolandBall and Many Other Balls

Description \(n\)个球,每组一个或者相邻的两个,求分成\(k\)组的方案数.\(n\leqslant 10^9,k<2^{15}\) Solution DP+FNT. 转移\(f[i][j]=f[i-1][j]+f[i-1][j-1]+f[i-2][j-1]\) 这个不是很好维护...可以看成多项式来做...可惜我也不太会... 还有一个转移就是折半来做,前一段为\(x\),后一段为\(y\),\(x+y=i\). 若恰好在\(x,y\)之间可以分开那么方案数就是 \(f[i][

codeforces #306D Polygon 构造

题目大意:给定n,要求构造一个凸n边形,使得每个内角都相同,每条边长度都不同 膜拜题解 其实我一开始想的是构造一个正n边形然后把每条边微移一下--不过似乎不是很好写的样子= = #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 110 #define PI 3.14159265358979

Codeforces gym102222 B.Rolling The Polygon 凸包/余弦定理

题意: 有一个不保证凸的多边形,让你滚一圈,计算某点滚出的轨迹多长. 题解: 求出凸包后,以每个点为转轴,转轴到定点的距离为半径,用余弦定理计算圆心角,计算弧长. #include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; int main() { int t,case1=0; cin>>t; while(t--) { cas