列表

详情


NC229623. Mike and Foam

描述

MikeRico酒吧的调酒师。在Rico酒吧,他们将啤酒杯放在一个特殊的架子上。在Rico酒吧,有n种啤酒编号从1n。第i瓶啤酒上面有 毫升的泡沫。

MaximMike的老板。今天他让Mike回答q个查询。最初架子是空的。在每个操作中,Maxim给他一个编号X。如果编号为X的啤酒已经在架子上,那么Mike应该从架子上取下它,否则他应该把它放在架子上。

每次询问后,Mike应该告诉他架子的分数。他们认为货架的分数是满足并且的数对(i,j)的个数。

Mike现在很累。所以他请你帮他处理这些操作。

输入描述

第一行输入包含数字nq),不同种类的啤酒数量和查询次数。
下一行包含n个由空格分隔的整数,( ),表示各种啤酒顶部的泡沫量。
接下来q行一行包含一个查询。每个查询一个整数X),表示应从货架上添加或移除的啤酒的编号。

输出描述

对于每一个查询,用一行输出对应的答案。

示例1

输入:

5 6
1 2 3 4 6
1
2
3
4
5
1

输出:

0
1
3
5
6
2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 993ms, 内存消耗: 12576K, 提交时间: 2022-10-02 17:41:54

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), 1
using namespace std;

const int N = 5e5 + 10;

typedef long long LL;

int n, q, k;
int cnt, p[N], moi[N], a[N];
bool st[N], vis[N];
LL ans, f[N];

void init()
{
	moi[1] = 1;
	for(int i = 2; i <= N; i ++)
	{
		if(!st[i]) p[cnt ++] = i, moi[i] = -1;

		for(int j = 0; i * p[j] <= N; j ++)	
		{
			st[i * p[j]] = 1;
			if(i % p[j] == 0) break;
			moi[i * p[j]] = -moi[i];
		}	
	}	
}

void sovle(bool x, int id)
{
	int n = a[id];
	for(int i = 1; i * i <= n; i ++)
	{
		if(n % i) continue;
		
		ans -= (f[i] - 1) * f[i] / 2 * moi[i];
		f[i] += (x) ? 1 : -1;
		ans += (f[i] - 1) * f[i] / 2 * moi[i];
		
		if(i * i == n) return ;
		 
		int j = n / i;
		ans -= (f[j] - 1) * f[j] / 2 * moi[j];
		f[j] += (x) ? 1 : -1;
		ans += (f[j] - 1) * f[j] / 2 * moi[j];
	}	
}

int main()
{
	IOS;
	init();

	cin >> n >> q;
	for(int i = 1; i <= n; i ++)
		cin >> a[i];
		
	while(q --)
	{
		cin >> k;
		vis[k] ^= 1;
		sovle(vis[k], k);
		cout << ans << endl;
	}
	
	return 0;
}

C++ 解法, 执行用时: 526ms, 内存消耗: 5960K, 提交时间: 2022-03-05 16:56:57

#include <bits/stdc++.h>
using namespace std;
#define N 100005
 
int a[2 * N], n, b[5 * N], vis[2 * N], q[N], qs;
long long ans;
 
void func(int v, int x, int y, int d) {
	if (x == qs) {
		if(v) {
			b[y] --;
			if (d) ans += b[y];
			else ans -= b[y];
		}
		else {
			if (d) ans -= b[y];
			else ans += b[y];
			b[y] ++;
		}
	}
	else {
		func(v, x + 1, y, d);
		func(v, x + 1, y * q[x], 1 - d);
	}
}
 
int main() {
	int i, k, m, d, qr;
	scanf("%d %d", &n, &qr);
	for (i = 1; i <= n; i ++) scanf("%d", a + i);
	while (qr --) {
		scanf("%d", &k);
		d = a[k]; m = sqrt(d); qs = 0;
		for (i = 2; i <= m; i ++) {
			if (d % i == 0) q[qs ++] = i;
			while (d % i == 0) d /= i;
		}
		if (d > 1) q[qs ++] = d;
		func(vis[k], 0, 1, 0);
		vis[k] ^= 1;
		printf("%lld\n", ans);
	}
}

上一题