• cf980d Perfect Groups


    题意

    定义一个串的权值是将其划分成 (k) 组,使得每一组在满足“从组里选出一个数,再从组里选出一个数,它们的乘积没有平方因子”这样的前提时的最小的 (k)。每组的数不必相邻, 不必连续。

    现在给你一串数,问你,权值为 (1,2,ldots,n) 的子串分别有多少个。

    解答

    显然如果一个数中含有平方因子,抹去平方因子也不会对答案产生影响。

    因此对于一个串,抹去平方因子后,有多少种不同的数,权值就是多少。注意要特判 (0)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <map>
    using namespace std;
    int n, a[5005], cnt, b[5005], ans[5005];
    map<int,int> mp;
    bool vis[5005];
    int f(int x){
    	if(x>=-1 && x<=1)	return x;
    	int flg=1;
    	if(x<0){
    		flg = -1;
    		x *= -1;
    	}
    	for(int i=2; i<=10000; i++){
    		if(i*i>x)	break;
    		while(x%(i*i)==0)
    			x /= i * i;
    	}
    	return x*flg;
    }
    int main(){
    	cin>>n;
    	for(int i=1; i<=n; i++){
    		scanf("%d", &a[i]);
    		a[i] = f(a[i]);
    		if(!mp[a[i]]){
    			mp[a[i]] = ++cnt;
    			b[i] = cnt;
    		}
    		else	b[i] = mp[a[i]];
    	}
    	for(int i=1; i<=n; i++){
    		cnt = 0;
    		memset(vis, 0, sizeof(vis));
    		for(int j=i; j<=n; j++){
    			if(a[j]==0){
    				if(!cnt)	ans[1]++;
    				else	ans[cnt]++;
    			}
    			else{
    				if(!vis[b[j]]){
    					vis[b[j]] = true;
    					cnt++;
    				}
    				ans[cnt]++;
    			}
    		}
    	}
    	for(int i=1; i<=n; i++)
    		printf("%d ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    你不知道的正则表达式
    浅谈apache网页优化及方法
    Web基础与HTTP协议
    nfs
    Vi编辑器的工作模式
    磁盘管理和磁盘配额
    系统安全及应用
    正则表达式与文本编辑器
    读书笔记_java设计模式深入研究 第三章 工厂模式 Factory
    JavaScript模式读书笔记 第7章 设计模式
  • 原文地址:https://www.cnblogs.com/poorpool/p/9047866.html
Copyright © 2020-2023  润新知