Codeforces Round #694 (Div. 2)D.Strange Definition

Posted lasomisolaso~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #694 (Div. 2)D.Strange Definition相关的知识,希望对你有一定的参考价值。

题意

给出 x , y x, y x,y相邻的定义:如果 l c m ( x , y ) g c d ( x , y ) \\fraclcm(x,y)gcd(x,y) gcd(x,y)lcm(x,y) 是平方数,则称 x , y x, y x,y两个数相邻。
给出一个长度为 n n n的数列,每过一秒钟,数列中的每一个元素会被与它相邻的所有元素的乘积(包括它自身)所替换。
给出 q q q个询问,问在第 w i w_i wi秒时,当前数列中哪个元素有最多的相邻元素,不需要给出这个元素是谁,只要给出它的相邻元素个数。

题解

首先, l c m ( x , y ) = x ∗ y g c d ( x , y ) lcm(x, y) = \\fracx*ygcd(x,y) lcm(x,y)=gcd(x,y)xy,得出 l c m ( x , y ) g c d ( x , y ) = x ∗ y g c d ( x , y ) 2 \\fraclcm(x,y)gcd(x,y) = \\fracx*ygcd(x,y)^2 gcd(x,y)lcm(x,y)=gcd(x,y)2xy.
如果 x ∗ y g c d ( x , y ) 2 = z 2 \\fracx*ygcd(x,y)^2 = z^2 gcd(x,y)2xy=z2 是平方数, 则 x ∗ y = z 2 ∗ g c d ( x , y ) 2 x*y = z^2 * gcd(x,y)^2 xy=z2gcd(x,y)2也是平方数。也可知如果 x ∗ y x*y xy是平方数, x ∗ y g c d ( x , y ) 2 \\fracx*ygcd(x,y)^2 gcd(x,y)2xy也一定是平方数。
所以, l c m ( x , y ) g c d ( x , y ) \\fraclcm(x,y)gcd(x,y) gcd(x,y)lcm(x,y) 是平方数当且仅当 x ∗ y x*y xy是平方数。
x ∗ y x*y xy是平方数,那么 x ∗ y x*y xy分解质因数后,每个质因数的指数必定是偶数,那么 x x x y y y分别分解质因数后其质因数的指数奇偶性必定相同。
也就是说,质因数的指数是多少已经不重要,只关心它们的奇偶性,那么就将指数模 2 2 2变成 0 0 0 1 1 1。将质因数指数 01 01 01相同的数分成一组,它们之间质因数的指数奇偶性都相同,也就互相相邻。这样就能统计某一时刻最多的相邻元素个数了。

下面考虑每一个时刻的情况是怎么样的。

可以发现如果一个组内元素个数是偶数,那么经过一秒后,它们的质因数指数都将变成 0 0 0(相乘时指数相加,偶数个1相加模2是0)。也就是说这样的组连同本来质因数指数就全是偶数的小组合成了一组。
如果组内元素个数是奇数,经过一秒后,它们的乘积的质因数指数将与它们完全一致(奇数个 1 1 1相加依然是奇数)。就是说它们不会改变。
那么就能得出结论, 1 1 1秒及之后的时间情况都是和 1 1 1秒的时候相同的,答案只要考虑 0 0 0秒和 1 1 1秒之后两种情况。
具体统计某个 01 01 01情况,可以将指数是奇数的质因数记录下来,如果两个数这些指数为 1 1 1的质因数相同,那么它们就是同一组的。
可以用将指数是奇数的质因数 h a s h hash hash记录,用 m a p map map维护每个 h a s h hash hash值有多少元素。具体见代码。

代码

/*
 * @file D.cpp
 * @path D:\\code\\ACM\\codeforces\\Div2_694\\D.cpp
 * @author Xiuchen
 * @date  2021-01-06 00:06:22
*/

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<cmath>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<unordered_map>
//#define DEBUG
#define M_PI 3.14159265358979323846
#define dbg(x) cout << #x << " = "<< (x) << endl
#define dbg2(x1,x2) cout << #x1 << " = " << x1 << " " << #x2 << " = " << x2 << endl
#define dbg3(x1,x2,x3) cout<< #x1 << " = " << x1 << " " << #x2 << " = " << x2 << " " << #x3 << " = " << x3 <<endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 3e5 + 100;
const ll base = 19260817;
int gcd(int a, int b)
    return b ? gcd(b, a % b) : a;

int t, n;
int a[maxn];
map<ull, int> mp;
void fun(int x)
    ull tmp = 0;
    vector<int> v;
    for(int i = 2; i * i <= x; i++)
        if(x % i == 0)
            int cnt = 0;
            while(x % i == 0) cnt++, x /= i;
            if(cnt & 1) v.push_back(i);
        
    
    if(x > 1) v.push_back(x);
    for(auto &it : v) tmp = tmp * base + it;
    mp[tmp]++;

int main()
#ifdef DEBUG
    freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif
    scanf("%d", &t);
    while(t--)
        mp.clear();
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
            fun(a[i]);
        
        int ansa = 0, ansb = 0;
        for(auto it = mp.begin(); it != mp.end(); it++)
            ansa = max(ansa, it->second);
            if((it->second) % 2 == 0 || it->first == 0) ansb += it->second;
        
        ansb = max(ansa, ansb);
        int q;
        scanf("%d", &q);
        while(q--)
            ll w;
            scanf("%lld", &w);
            if(w == 0) printf("%d\\n", ansa);
            else printf("%d\\n", ansb);
        
    
    return 0;

以上是关于Codeforces Round #694 (Div. 2)D.Strange Definition的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)

Codeforces Global Round 19

Codeforces Educational Codeforces Round 67

Codeforces Round 1132Educational Round 61