CF 980D Perfect Groups(数论)

CF 980D Perfect Groups(数论)

一个数组a的子序列划分仅当这样是合法的:每个划分中的任意两个数乘积是完全平方数。定义a的权值为a的最小子序列划分个数。现在给出一个数组b,问权值为i的b的子串个数。

这题意真不是人类智慧能轻易描述的。据说此题在比赛场上读题30min,做题5min,做完还WA。果然是坑题。

如果有两个数a和b,a和b的乘积是完全平方数,那么如果a有因子x^2,那么x^2就可以去掉,使a变成a/x^2,结论依然成立。因此我们把所有数的质因子次数mod2,可以发现结论仍然不变。

因此,在一个划分内的数必须完全相同或者有数为零(涉及乘除法一定要考虑零啊啊啊)。n^2dp即可。

#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=5005;
int n, a[maxn], b[maxn], cnt[maxn];  //cnt[i]储存i有几个
int k, ans[maxn], id0;

int deal(int x){
    int flag;
    if (x<0) x=-x, flag=-1; else flag=1;
    for (int i=2; i*i<=x; ++i)
        while (x%(i*i)==0) x/=i*i;
    return x*flag;
}

int main(){
    scanf("%d", &n); int t; id0=-1;
    for (int i=1; i<=n; ++i){
        scanf("%d", &t), a[i]=b[i]=deal(t);
        if (!a[i]) id0=0;
    }
    sort(b+1, b+1+n);
    if (!id0) id0=lower_bound(b+1, b+1+n, 0)-b;
    for (int i=1; i<=n; ++i)
        a[i]=lower_bound(b+1, b+1+n, a[i])-b;
    for (int i=1; i<=n; ++i){
        for (int j=1; j<=n; ++j) cnt[j]=0; k=0;  //k:[i,j]不同元素的数目
        for (int j=i; j<=n; ++j){
            if (a[j]==id0){
                if (!k) ++ans[1]; else ++ans[k];
                continue;
            }
            if (!cnt[a[j]]) ++k;
            ++cnt[a[j]]; ++ans[k];
        }
    }
    for (int i=1; i<=n; ++i) printf("%d ", ans[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/MyNameIsPc/p/9053087.html

时间: 2024-07-31 05:33:14

CF 980D Perfect Groups(数论)的相关文章

Codeforces 980D Perfect Groups

题目大意 设有一个数组A和对A的一个操作f.那么f(A)返回一个最小的k,使得A能分成k组(每组元素不一定连续,但每个元素一定属于某一组),且每组里的任意两个元素的乘积是完全平方数. 现有一个长度为n的数组A,问有多少中情况,从A中取出一段连续的子序列B,使f(B)=k(k = 1...n) 解题思路 首先考虑操作f中的某一组中的某两个数a和b.因为\[ab = k^2(k \in Z)\]所以我们有\[a = \alpha^2t_1\]和\[b=\beta^2t_2\](α.β为整数且t1.t

CF980D Perfect Groups

思路: 注意到若A * B和B * C都是完全平方数,则A * C也是完全平方数,就不难解答了,要特判0的情况. 实现: 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 5005; 4 int a[MAXN], par[MAXN], buf[MAXN]; 5 typedef long long ll; 6 void init(int n) 7 { 8 for (int i = 0; i < n; i

Codeforces Round #480 (Div. 2) C 贪心 D 数字、思维 E 树上倍增

Codeforces Round #480 (Div. 2) C. Posterized 题意: 给出 n 个数,都是区间 [0,255] 内的数,要你把 [0,255] 划分成多个长度 <=k 的不重叠的子区间.每个数必须包含在一个子区间内,且这个数的价值是这个子区间的左端点.要你输出这 n 数的价值,且这 n 个价值字典序要最小. tags: 首先很明显字典序最小,那对于第 i 个数 p[i] 定它的区间时,左端点肯定要尽可能小.所以我们直接枚举区间 [ p[i]-k+1, p[i] ] 定

屏姨讶们是h25vhc4y6ece5

说到这里,玄老的声音中明显多了几分悲怆的味道"他们都是好孩子,尽管他们未能真正毕业,但在学院的名册上,始终有着他们的名字.他们以学院的理想为理想,他们并不是没有毕业的实力,而是为了学院的理想战死了."-----------------------------------------------------------------------------周漪忍不住道:"有什么是学院不能帮你解决的?非要自己一个人去面对?难道你说出来我们会不帮你么?"可是--,聚能魂导炮

僦檬哨招瓤kdqg84x5hodqk1

台上,天煞斗罗黄津绪并没有催促双方进行下一场比赛,因为比赛台在刚才一战中被破坏的实在是太厉害了,马小桃的黑色凤凰火焰足足灼烧了一分多钟才消失.如果不进行修补,已经没法再继续比赛了.此时正由几位实力不俗的土系魂师快速修复着.自从进入史莱克学院之后,他们一直都在紧张的学习和修炼,哪有什么放松的时间.凌落宸的疑问则只是落在霍雨浩一个人身上,"极致之冰?"贝贝心中早有定计,低声道:"第一场我们赢了,我们就已经处于主动之中.我们现在最希望出现的.是第二场他们在冲动之下派出两名魂王,或者

滦谇淋坌招r6un44y803l1xog9y18

求收藏.求推荐票.求会员点击.刺入他额头的青色噬灵刻刀轻微震颤,奇异的是,那破入的创口并没有鲜血流出,反而是那噬灵刻刀竟然缓缓软化,化为青碧色的液体顺着那创口流入霍雨浩头部之中.霍雨浩呵呵一笑,道:"发现就发现呗,王冬,你现在是不是觉得特别虚弱,一点力气都用不出来啊?""战争最后虽然胜利了,但我们唐门暗器的作用也受到了极大的质疑.从那以后,各国开始大幅度削减对我们制作暗器的采购.而我们唐门赚钱虽然不少,但按照第一代门主的意思,大部分收入全都捐赠了出去.用来改善穷苦地区的平民生

UVA 10622 - Perfect P-th Powers(数论)

UVA 10622 - Perfect P-th Powers 题目链接 题意:求n转化为b^p最大的p值 思路:对n分解质因子,然后取所有质因子个数的gcd就是答案,但是这题有个坑啊,就是输入的可以是负数,负数的情况比较特殊,p只能为奇数,这时候是要把答案不断除2除到为奇数即可. 代码: #include <stdio.h> #include <string.h> #include <math.h> long long n; int prime[333333], vi

UVa 10622 - Perfect P-th Powers(数论)

#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; int find(int n) { for (int i = 2 ; i < 50000 ; ++ i) { if (pow(0.0+i, (int)(log10

cf 319 div 2 Modulo Sum 数论+DP

 Modulo Sum 题目抽象:给你你一个整数数组,能否从中取出一些树,使得他们的和能被m整除. 分析:见代码注释. 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int MS = 1000005; 5 int n, m; 6 int cnt[MS], r[MS], tem[MS]; 7 int main() { 8 scanf("%d%d", &n, &