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 }