数论 集合? 集合!

wxy总是闲不住,有一天,他又给cc出难题,他的问题是这样的:给你n个数字的集合,n个数字有(n*(n+1))/2连续子区间,对于每个连续子区间,你需要将这个子区间的数分为尽量少的集合, 使得每个集合中任意两个数的乘积是完全平方数,(在对子区间进行划分时,不要求每个子区间内数在原集合中连续。)

第一行一个整数n,集合大小,(1<=n<=5000); 第二行n个整数a1,a2,…,an(-10^8≤ai≤10^8)

输出n个数 ,每个数表示可以划分的集合大小是i的总数(1<=i<=n);

 

 

思路

a*b为完全平方数,当且它们去掉所有偶数次方的质因子,剩下的数相同,注意一下a【i】=0.

因为数的大小为10的8次方,数组存不下,所以要离散化

#include <stdio.h>
#include <math.h>
#include<set>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=500005;
int a[maxn],b[maxn],c[maxn],vis[maxn];
int kabs(int x)
{
    if(x<0)
        return -x;
    else
        return x;
}
int main()
{
    int i,j,k,num,h,t,n,x,cnt;
    scanf("%d",&n);
    cnt=0;
    for(i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=0)
            cnt++;
    }
    if(cnt==0)
    {
        printf("%d",n*(n+1)/2);
        for(i=2; i<=n; i++)
            printf(" 0");
        printf("\n");
    }
    else
    {
        for(i=1; i<=n; i++)
        {
            k=kabs(a[i]);
            for(j=2; j*j<=k; j++)
            {
                t=j*j;
                if(a[i]%t==0)
                {
                    while(a[i]%t==0)
                    {
                        a[i]=a[i]/t;
                    }
                }
            }
        }
        for(i=1; i<=n; i++)
            c[i]=a[i];
        sort(c+1,c+n+1);
        int len=unique(c+1,c+n+1) - c;
        for(i=1; i<=n; i++)
        {
            if(a[i]==0)
                continue;
            a[i]=lower_bound(c+1,c+len+1,a[i]) - c;
        }
        memset(b,0,sizeof(b));
        for(i=1; i<=n; i++)
        {
            memset(vis,0,sizeof(vis));
            num=0;
            for(j=i; j<=n; j++)
            {
               if(!vis[a[j]]&&a[j]!=0)
               {
                   vis[a[j]]=1;
                   num++;
               }
               if(num==0)
               b[num+1]++;
               else
                b[num]++;
            }
        }
          for(i=1;i<=n;i++)
            printf("%d ",b[i]);
    }
    return 0;
}

 

InputOutput

2
5 5

3 0

5
5 -4 2 1 8

5 5 3 2 0

posted @ 2018-07-18 17:27  电竞毒奶  阅读(170)  评论(0编辑  收藏  举报