zoukankan      html  css  js  c++  java
  • CF980D Perfect Groups

    题目链接:http://codeforces.com/contest/980/problem/D

    题目大意:

      对于 (n) 个数,考虑它的所有子串,每个个子串中的数字最少能分成 (k) 组,使得每一组中的所有数对之积都为完全平方数。对于每一个 (k) ,输出相应的子串数。

    知识点:  算术基本定理

    解题思路:

      对完全平方数进行质因数分解,不难发现它的所有质因数的指数都为偶数。因此两个数之积若为完全平方数,则这两者的所有质因子的指数之和必为偶数。对此,我们只需要考虑每个数的指数为奇数的质因子(若指数为偶数对于积的质因数的奇偶性没有影响),若两个数的指数为奇数的质因子相同,则二者相乘即得完全平方数。

    AC代码:

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 const int maxn = 5000+5;
     5 
     6 int ans[maxn],a[maxn];
     7 
     8 int trans(int x){    //将 x 转化成由其指数为奇数的质因子相乘而得到的数
     9     if(x==0||x==1||x==-1)    return x;
    10 
    11     int ret=1;
    12     if(x<0){
    13         ret=-1;
    14         x=-x;
    15     }
    16     for(int i=2;i*i<=x;i++){
    17         if(x%i==0){
    18             int has=0;
    19             while(x%i==0){
    20                 has++;
    21                 x/=i;
    22             }
    23             if(has%2==1)
    24                 ret*=i;
    25         }
    26     }
    27     return ret*x;
    28 }
    29 
    30 map<int,int>vis;
    31 int ind[maxn];
    32 bool used[maxn];
    33 int main(){
    34     int n;
    35     scanf("%d",&n);
    36     int cnt=0;
    37     for(int i=1;i<=n;i++){
    38         scanf("%d",&a[i]);
    39         a[i]=trans(a[i]);
    40 
    41 //以下是一个 O(n*n) 的暴力
    42         int t=vis[a[i]]; 
    43         if(!t){
    44             cnt++;
    45             vis[a[i]]=cnt;
    46             ind[i]=cnt;
    47         }
    48         else
    49             ind[i]=t;
    50     }
    51 
    52     for(int i=1;i<=n;i++){
    53         memset(used,false,sizeof(used));
    54         cnt=0;
    55         for(int j=i;j<=n;j++){
    56             if(a[j]==0){
    57                 if(cnt==0)  ans[1]++;
    58                 else    ans[cnt]++;
    59             }
    60             else{
    61                 if(!used[ind[j]]){
    62                     used[ind[j]]=true;
    63                     cnt++;
    64                 }
    65                 ans[cnt]++;
    66             }
    67         }
    68     }
    69     for(int i=1;i<=n;i++){
    70         if(i!=1)    printf(" ");
    71         printf("%d",ans[i]);
    72     }printf("
    ");
    73 
    74     return 0;
    75 }    
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    Revit 二次开发 交互及UIAPI之TaskDialog
    Revit 二次开发 交互及UIAPI之Selection
    Revit 二次开发 元素创建与修改练习
    编译带libev和libuv的libwebsocket (Win平台)
    sqlite3存储格式
    MAC OS下编译apple跨平台的libevent库 (可延申到其它第三库)
    Unix, Linux以及NT内核和它们各自衍生的系统关系图
    简单地迁移你的android jni代码逻辑到iOS
    使用ndk交叉编译android各平台版本的第三方库
    使用Android Studio进行ndk开发的准备
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/9043311.html
Copyright © 2011-2022 走看看