【20200202】【lyk】CR614 1D Chaotic V.题解

题目

http://codeforces.com/contest/1292/problem/D

解题思路

从1结点出发,每次枚举是否有大小大于n/2的子树,递归至终点即可

#include <iostream>

using namespace std;
int p[10101],cnt = 0,n,num[10101],sum[10101],t[5050],m[5050][777];
bool notp[10101];

inline int calc(int x,int y) {
 int ret = 0;
 x /= y;
 while (x) {
  ret += x;
  x /= y;
 }
 return ret;
}
void init() {
 for (int i = 2;i <= 5000; i++) {
  for (int j = 2;j *i <= 5000; j++) {
   notp[i*j] = 1;
  }
  if (!notp[i])
   p[++cnt] = i;
 }
  for (int i = 2;i <= 5000; i++) {
  int tmp = i;
  for (int j = 1;j <= cnt; j++) {
   while (!(tmp%p[j]))
    tmp /= p[j],num[i]++;
  }
  sum[i] = sum[i-1]+num[i];
 }
 for (int i = 1;i <= 5000; i++) {
  for (int j = 1;j <= cnt; j++)
   m[i][j] = calc(i,p[j]);
 }
}
long long ans = 0;
inline void dfs(int st,int ed,int pos,int ci) {
// cout << st << " " << ed << " " << pos << " " << ci << " " << p[pos] << endl;
 int tot = 0,tmp = ci+1,last = ed;
 for (int i = ed;i >= st; i--) {
  //cout << i << " " << tmp << endl;
  if (m[i][pos] >= tmp)
   tot += t[i];
  else {
  // cout << i << " " << tmp << endl;
   if (tot+tot > n) {
    ans -= tot+tot-n;
    dfs(i+1,last,pos,tmp);
    return ;
   }
   pos--;
   while (!m[i][pos] && pos) {
    pos--;
   }
   if (!pos)
    return ;
   last = i;
   tot = t[i];
   tmp = 1;
  }
 }
 if (tot+tot > n) {
  ans -= tot+tot-n;
  dfs(st,last,pos,tmp);
 }
}


int main() {
 init();
  int aa;
 scanf("%d",&n);
 for (int i = 1;i <= n; i++) {
  scanf("%d",&aa);
  ans += sum[aa];
  t[aa]++;
 }
 dfs(0,5000,cnt,0);
 printf("%I64d",ans);
 return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值