首页 > 其他分享 >Codeforces Round #694 (Div. 1) - B. Strange Definition

Codeforces Round #694 (Div. 1) - B. Strange Definition

时间:2022-10-10 00:00:16浏览次数:81  
标签:Definition 连通 694 10 int scanf Codeforces 分解 mp

数论

Problem - B - Codeforces

题意

给定 \(n\;(1<=n<=3*10^5)\) 个数 \(a[i]\), \(1<=a[i]<=10^6\)

把 \(a[i]\) 看做是 n 个点的点权

如果 \(\frac {lcm(a[i],a[j])}{gcd(a[i],a[j])}\) 是完全平方数,则可以给 \(i\lrarr j\) 连一条无向边

每秒后都会令每个连通块中的每个点的点权变为整个连通块的点权乘积,有 \(q\;(1<=q<=3*10^5)\) 次询问,每次回答 \(w\) 秒后最大的连通块大小

思路

  1. \(\frac {lcm(a[i],a[j])}{gcd(a[i],a[j])}\) 是完全平方数 \(\Lrarr\) \(a[i]*a[j]\) 是完全平方数

  2. 设 \(a[i]=p_1^{s_1}*p_2^{s_2}*...p_n^{s_n}\), 我们不关心 \(s_i\) 具体是多少,只需要关心 \(s_i\) 的奇偶性,因此令 \(y=p_1^{s_1mod\;2}*p_2^{s_2mod 2}*...p_n^{s_nmod\;2}\)

  3. 初始时某个连通块有 3 种情况

    1. 每个点点权的 y 都为 1
    2. 每个点点权的 y 不为 1,连通块的大小是偶数
    3. 每个点点权的 y 不为 1,连通块的大小是奇数
  4. w = 0 时,求连通块大小的最大值即可;

    w >= 1 时,第 2 种连通块会转换为 1,第 3 种永远是第 3 种,因此把 2 转换成 1,再求 max(第 1 种的大小,第 3 种的大小的最大值)

  5. 实际上不需要建边跑并查集,复杂度太高;

    用 y 来表示即可,枚举 \(a[i]\), 分解 \(a[i]\) 求出对应的 y,\(mp[y]++\);

    \(mp[1]\) 就是第一种连通块的大小;其余的 y 也可用 \(mp[y]\mod2\) 来判断其大小的奇偶性,详细见代码

  6. 第 2 步的分解有两种方法:

    1. 线性筛 \(\sqrt{max(a[i])}\) 内的素数,用素数来分解,复杂度为线性筛的 \(O(1000)\), 分解单个数的 \(O(\frac {\sqrt {a[i]}}{\ln{\sqrt{a[i]}}})\)
    2. 线性筛 \(max(a[i])\) 内的素数,并在线性筛中预处理除 \(p[i]\) 表示 \(i\) 的最小质因子为 \(p[i]\);分解时每次就可以精准找到下一个要除的素数,复杂度为 线性筛的 \(O(10^6)\), 分解单个数的 \(O(\log {a[i]})\)

    当值域较小且要分解的数较多时用第 2 种更好

代码

#include <bits/stdc++.h>
using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;

const int N = 3e5 + 10, M = 1e6 + 10;
int n;
int a[N];
int pr[M / 5], p[M], cnt;
void get_primes(int n)
{
	p[1] = 1;
	for (int i = 2; i <= n; i++)
	{
		if (!p[i])
		{
			pr[++cnt] = i;
			p[i] = i;
		}
			
		for (int j = 1; j <= cnt && pr[j] <= n / i; j++)
		{
			p[i * pr[j]] = pr[j];
			if (p[i] == pr[j])
				break;
		}
	}
}
map<int, int> mp;
void fenjie(int x)
{
	int y = 1;
	while(x > 1)
	{
		int k = 0;
		int minp = p[x];
		while(x % minp == 0)
		{
			k++;
			x /= minp;
		}
		if (k & 1)
			y *= minp;
	}
	mp[y]++;
}
int main()
{
	int T;
	scanf("%d", &T);
	get_primes(M - 10);
	while(T--)
	{
		scanf("%d", &n);
		mp.clear();
		for (int i = 1; i <= n; i++)
		{
			int x;
			scanf("%d", &x);
			fenjie(x);
		}
		int ans0 = 0;
        //w = 0
		for (auto &[y, t] : mp)
			ans0 = max(ans0, t);
        //w >= 1
		int ans1 = 0;
		for (auto &[y, t] : mp)
		{
            //把第 2 种变成第 1 种
			if (y != 1 && t % 2 == 0)
			{
				mp[1] += t;
				mp[y] = 0;
			}
		}
		for (auto &[y, t] : mp)
			ans1 = max(ans1, t);
		int q;
		scanf("%d", &q);
		while(q--)
		{
			int w;
			scanf("%d", &w);
			if (w >= 1)
				printf("%d\n", ans1);
			else
				printf("%d\n", ans0);
		}
	}
    return 0;
}

标签:Definition,连通,694,10,int,scanf,Codeforces,分解,mp
From: https://www.cnblogs.com/hzy717zsy/p/16774175.html

相关文章

  • definitions.json
     AdvancedRestClient的下载包链接:​​下载包​​​ 提取码:ofl3  还需要一个definitions.json 文件,从网上找的时候,都是需要积分的。然后去github上找了源码definit......
  • Codeforces:B. New Year and Ascent Sequence[模拟]
    题面Asequencea=[a1,a2,…,al]oflengthlhasanascentifthereexistsapairofindices(i,j)suchthat1≤i<j≤landai<aj.Forexample,thesequence[0,2......
  • Codeforces Round #800 div1 B
    B.FakePlasticTrees看了第三个样例发现一个节点可以由他的几个子节点一起构成我们首先自下而上的看肯定叶子节点越大越好这样我们选择的空间就会越多再者要是我们......
  • 「题解」Codeforces 1572B Xor of 3
    我知道你很急,但你先别急。我急了我急了我急了。如果直接上去莽构造的话,很可能就是像我一样大分讨的后果。先特判掉全是1,或者1的个数是奇数的情况。我的做法是考虑所......
  • Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideExcep
    这个问题整到 凌晨1:36,网上搜了很多个文章,解决方案都不对。有的都在乱说。这类问题很多都是英文文章,没见说明白的,中文解决方案几乎没有。另外也看到了类似的问题,其实这个问......
  • Codeforces Round #822 (Div. 2)
    A题意给一个长为n的数组,每次可以对其中某个数做+1或-1的操作。求最小的操作次数,使得可以从数组中选出三个相同的数。思路很容易可以想到选三个最接近的数然后操作。也......
  • Codeforces.1305B Kuroni and Simple Strings[模拟]
    题面NowthatKuronihasreached10yearsold,heisabigboyanddoesn'tlikearraysofintegersaspresentsanymore.ThisyearhewantsaBracketsequencea......
  • Codeforces补入门题
    CodeforcesRound#620(Div.2)LongestPalindrome题意给定n个长度为m的字符串,使用其中尽可能多的字符串构成一个回文串输出回文串长度及该回文串(顺序可以乱)分析由于......
  • [题解] Codeforces Dytechlab Cup 2022 1737 A B C D E 题解
    傻*Dytechlab还我rating!(不过目前rating还没加上去,据说E是偷的说不定要unrated)实在没预料到会打成这样。。。求点赞点我看题A.ElaSortingBooks从前往后一位一位确......
  • [CodeForces-1198E] Rectangle Painting 2
    题解:朴素做法,是最小点覆盖点数是n*n,考虑离散化后,把每个矩形块看作点,跑最小点权覆盖。将矩形:左下角(x1,y1)到右上角(x2,y2)的x2++,y2++,那么这样离散化后每个x1<=x<x2,y1......