CodeForces - 819D,扩展欧几里得

After studying the beacons Mister B decided to visit alien’s planet, because he learned that they live in a system of flickering star Moon. Moreover, Mister B learned that the star shines once in exactly T seconds. The problem is that the star is yet to be discovered by scientists.

There are n astronomers numerated from 1 to n trying to detect the star. They try to detect the star by sending requests to record the sky for 1 second.

The astronomers send requests in cycle: the i-th astronomer sends a request exactly a**i second after the (i - 1)-th (i.e. if the previous request was sent at moment t, then the next request is sent at moment t + a**i); the 1-st astronomer sends requests a1 seconds later than the n-th. The first astronomer sends his first request at moment 0.

Mister B doesn’t know the first moment the star is going to shine, but it’s obvious that all moments at which the star will shine are determined by the time of its shine moment in the interval [0, T). Moreover, this interval can be split into Tparts of 1 second length each of form [t, t + 1), where t = 0, 1, 2, …, (T - 1).

Mister B wants to know how lucky each astronomer can be in discovering the star first.

For each astronomer compute how many segments of form [t, t + 1) (t = 0, 1, 2, …, (T - 1)) there are in the interval [0, T) so that this astronomer is the first to discover the star if the first shine of the star happens in this time interval.

Input

The first line contains two integers T and n (1 ≤ T ≤ 109, 2 ≤ n ≤ 2·105).

The second line contains n integers a1, a2, …, a**n (1 ≤ a**i ≤ 109).

Output

Print n integers: for each astronomer print the number of time segments describer earlier.

Examples

Input

4 2
2 3

Output

3 1 

Input

5 4
1 1 1 1

Output

2 1 1 1 

Note

In the first sample test the first astronomer will send requests at moments t1 = 0, 5, 10, …, the second — at moments t2 = 3, 8, 13, … That’s why interval [0, 1) the first astronomer will discover first at moment t1 = 0, [1, 2) — the first astronomer at moment t1 = 5, [2, 3) — the first astronomer at moment t1 = 10, and [3, 4) — the second astronomer at moment t2 = 3.

In the second sample test interval [0, 1) — the first astronomer will discover first, [1, 2) — the second astronomer, [2, 3) — the third astronomer, [3, 4) — the fourth astronomer, [4, 5) — the first astronomer.

题意:相当于有t个石子,分别放在0~t-1这些位置,然后有n个人轮流去取,第一个人第一次取0号石子,之后第i个人取i-1个人后ai号石子,如果该石子已经被取过了就不算,问每个人能取得多少个石子

思路:令 s = ( ∑ i = 1 N a i ) m o d   t s = (\sum_{i=1}^Na_i) mod\ t s=(i=1Nai)mod t, b i = ( ∑ k = 2 i a i ) m o d   t , b 1 = 0 b_i = (\sum_{k=2}^ia_i)mod\ t,b_1 = 0 bi=(k=2iai)mod t,b1=0(表示第i个人第一次取到 b i b_i bi号石子),则如果第i个人能取到第 x i x_i xi号石子(不一定第一个取到),那么满足下式: b i + s ∗ k 1 ≡ x i + t ∗ k 2 b_i+s*k_1 \equiv x_i+t*k_2 bi+sk1xi+tk2,即方程 s ∗ k 1 + t ∗ k 2 ≡ x i − b i s*k_1+t*k_2 \equiv x_i-b_i sk1+tk2xibi(将 − k 2 -k_2 k2看成 k 2 k_2 k2)有解,即对于 g = g c d ( s , t ) g = gcd(s,t) g=gcd(s,t), x i ≡ b i ( m o d g ) x_i \equiv b_i(mod g) xibi(modg),即对于每个 b i m o d g b_i mod g bimodg相等的人能取到的石子都在一个环上,环上的石子编号满足 x i ≡ b i ( m o d   g ) x_i \equiv b_i(mod\ g) xibi(mod g),对于所有在同一个环上跳跃的人,必经过编号为 b i b_i bi%g号石子,设他们从取到的第一个石子跳到该石子所需步数为 c i c_i ci,设任意两个在同一个环上取石子的人i和j,他们跳跃到 b i b_i bi%g号石子的步数 c i c_i ci c j c_j cj刚好相邻,且cj < ci,那么i能取到的石子数刚好为cj-ci

#include<bits/stdc++.h>
#define MAXN 200005
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
	if(b == 0)
	{
		y = 0;
		x = 1;
		return a;
	}
	int r = exgcd(b,a%b,x,y);
	int tmp = y;
	y = x - (a/b)*y;
	x = tmp;
	return r;
}
int t,n,a[MAXN],s,ans[MAXN],k1,k2,len,nos[MAXN];
set<int> se[MAXN];
unordered_map<int,int> vis,id;
int main()
{
	while(~scanf("%d%d",&t,&n))
	{
		vis.clear();
		id.clear();
		for(int i = 0;i < MAXN;++i)
			se[i].clear();
		memset(ans,-1,4*n+4);
		a[0] = s = 0;
		for(int i = 1;i <= n;++i)
		{
			scanf("%d",&a[i]);
			s = (s + a[i]) % t;
		}
		a[1] = 0;
		for(int i = 2; i <= n;++i)
			a[i] = (a[i-1] + a[i] ) % t;
		int g = exgcd(s,t,k1,k2),cnt = 0,len = t / g;
		for(int i = 1;i <= n;++i)
		{
			if(!vis.count(a[i]))
			{
				vis[a[i]] = true;
				if(!id[a[i]%g])
					id[a[i]%g] = ++cnt;
				nos[i]=1LL*k1*(a[i]%g-a[i])/g%len;
				nos[i] = (nos[i] + len) % len;
				se[id[a[i]%g]].insert(nos[i]);
			}
			else
				ans[i] = 0;
		}
		
		for(int i = 1;i <= n;++i)
		{
			if(ans[i] == -1)
			{
				set<int>::iterator it = se[id[a[i]%g]].find(nos[i]);
				if(it == se[id[a[i]%g]].begin())
					it = --se[id[a[i]%g]].end();
				else
					--it;
				int s1 = nos[i],s2 = *it,tmp = s1-s2;
				ans[i] = tmp!=0?(tmp+len)%len:len;
			}
		}
		for(int i = 1;i <= n;++i)
			printf("%d ",ans[i]);
		printf("\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值