zoukankan      html  css  js  c++  java
  • 51nod挑的部分5级题

    最近心情不好所以写代码来获得快落

    4级题有点难做?然后就开始挑简单的5级题开始写

    然后准备记录一些自己没有做出来

    参考讨论区或者博客才做出来的题目

    51nod_1189 阶乘分数

    这个题参考了讨论区

    令 t = n!

    1/t = 1/x + 1/y , 0 < x <= y 的正整数解计数, n <= 1e6

    考虑对式子进行变换

    1/t = (x + y) / xy

    xy = t * (x + y)

    我们这时候应该有一个反应,配方有

    (x - t) * (y - t) = t * t

    所以考虑统计 t * t 的因子数就可以了

    分解质因数即可

     1 n, m, k = int(input()), 1, 1000000007
     2 v = [0 for i in range(n + 1)]
     3 p = [0 for i in range(n + 1)]
     4 for i in range(2, n + 1):
     5     if not v[i]:
     6         p[0] += 1
     7         p[p[0]] = i
     8         t, j = 1, i
     9         while j <= n:
    10             t += n // j * 2
    11             j *= i
    12         m = m * t % k 
    13     for j in range(1, p[0] + 1):
    14         if i * p[j] > n:
    15             break
    16         v[i * p[j]] = 1
    17         if i % p[j] == 0:
    18             break
    19 print ((m + 1) * pow(2, k - 2, k) % k)
    View Code

    51nod_1616 最小集合

    这个题参考了博客

    考虑 i 存在于原集合的条件

    假设 i 的倍数 s = {a * i, b * i, c * i ... } 存在于输入给定的集合中

    那么我们知道 d = gcd(a, b),d * i 肯定是存在于原集合中的

    那么必然存在 e = gcd(c, d),e * i 也存在于原集合中

    即 gcd(a, b, c ...) * i 必然存在于原集合中

    因为 i 要存在于原集合中只能依靠 s 中的元素

    又有gcd(s) >= 1 * i

    所以当且仅当 gcd(s) == i 的时候

    才有 i 存在于原集合

    枚举 i 即可

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int N = 1e6 + 5; 
     6 
     7 int n, m, k, b[N];
     8 
     9 int main() {
    10     ios::sync_with_stdio(false);
    11     cin >> n;
    12     for (int x, i = 1; i <= n; i ++) {
    13         cin >> x, k = max(x, k);
    14         if (!b[x]) b[x] = 1, m ++; 
    15     }
    16     for (int i = 1; i <= k; i ++) 
    17         if (!b[i]) {
    18             int t = 0;
    19             for (int j = i << 1; j <= k; j += i)
    20                 if (b[j])
    21                     t = __gcd(t, j);
    22             if (t == i) m ++;
    23         }
    24     cout << m;
    25     return 0;
    26 }
    View Code

    51nod_1586 约数和

    傻屌题目,考虑a[x] +y

    那么对b的x, 2x,3x..产生贡献

    那么对c的kx,容易发现贡献次数为f(k),f(k)为k的因数个数

    考虑到x是随机的,所以采用每次更新的时候O(n / x)更新

    查询O(1)回答的话,期望每次更新次数是O(logn)的,成了

    垃圾题目,c++ 提交的话,要开快读和快速输出...

    visual c++提交的话,直接scanf + printf就成了...

     1 #include <stdio.h>
     2 
     3 const int N = 1e6 + 5; 
     4 
     5 int n, m, a[N];
     6 
     7 long long b[N];
     8 
     9 int main() {
    10     int op, x, y;
    11     scanf("%d %d", &n, &m);
    12     for (int i = 1; i <= n; i ++)
    13         for (int j = i; j <= n; j += i)
    14             a[j] += 1;
    15     while (m --) {
    16         scanf("%d %d", &op, &x);
    17         if (op == 1) {
    18             scanf("%d", &y);
    19             for (int i = 1, j = x; j <= n; i ++, j += x) 
    20                 b[j] += y * a[i];
    21         }
    22         else printf("%lld
    ", b[x]);
    23     }
    24     return 0;
    25 }
    View Code
  • 相关阅读:
    java线程简要
    Unable to find explicit activity class
    用NetBeans生成jar文件
    Linux下三个可以修改环境变量的地方
    linux定时执行shell脚本
    sql server 性能调优之 SQL语句阻塞查询
    sql server 性能调优之 死锁排查
    IObit Advanced SystemCare 系统清理优化工具
    IDEA配置Maven
    maven的生命周期及常用命令的使用
  • 原文地址:https://www.cnblogs.com/ytytzzz/p/9189133.html
Copyright © 2011-2022 走看看