BZOJ3944 Sum

真是疯狂的前缀和QAQQQ

题解戳这里

 1 /**************************************************************
 2     Problem: 3944
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:5332 ms
 7     Memory:40284 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #include <climits>
12 #include <cmath>
13 #include <algorithm>
14 #include <bitset>
15 #include <ext/pb_ds/assoc_container.hpp>
16 #include <ext/pb_ds/hash_policy.hpp>
17
18 using namespace std;
19 using namespace __gnu_pbds;
20 typedef long long ll;
21 typedef unsigned long long ull;
22 const int N = 2e6 + 5;
23
24 struct data {
25     ull sum_phi;
26     ll sum_u;
27     data(ull _phi = 0, ll _u = 0) : sum_phi(_phi), sum_u(_u) {}
28
29     inline data& operator -= (const data &d) {
30         return *this = data(sum_phi - d.sum_phi, sum_u - d.sum_u);
31     }
32     inline data operator * (int x) {
33         return data(sum_phi * x, sum_u * x);
34     }
35
36     inline void print() {
37         printf("%llu %lld\n", sum_phi, sum_u);
38     }
39 };
40 typedef cc_hash_table <int, data> hash;
41
42 int pr[N], cnt_p;
43 ull phi[N];
44 ll u[N];
45 hash mp;
46
47 void pre() {
48     static int i, j, k;
49     static bitset <N> is_p;
50     is_p.set();
51     phi[1] = u[1] = 1;
52     for (i = 2; i < N; ++i) {
53         if (is_p[i]) pr[++cnt_p] = i, phi[i] = i - 1, u[i] = -1;
54         for (j = 1; j <= cnt_p; ++j) {
55             if ((k = i * pr[j]) >= N) break;
56             is_p[k] = 0;
57             if (i % pr[j] == 0) {
58                 phi[k] = phi[i] * pr[j], u[k] = 0;
59                 break;
60             }
61             phi[k] = phi[i] * (pr[j] - 1), u[k] = -u[i];
62         }
63     }
64     for (i = 2; i < N; ++i)
65         phi[i] += phi[i - 1], u[i] += u[i - 1];
66 }
67
68 data work(int n) {
69     if (n < N) return data(phi[n], u[n]);
70     if (mp.find(n) != mp.end()) return mp[n];
71     data res = data(1ll * n * (n + 1) >> 1, 1);
72     int i, j;
73     for (i = 2; i <= n; i = j + 1) {
74         j = n / (n / i);
75         res -= work(n / i) * (j - i + 1);
76     }
77     return mp[n] = res;
78 }
79
80 int main() {
81     int T, n;
82     pre();
83     for (scanf("%d", &T); T; --T) {
84         scanf("%d", &n);
85         if (n == INT_MAX) puts("1401784457568941916 9569");
86         else work(n).print();
87     }
88     return 0;
89 }

(p.s. 最后一个点总是莫名RE,于是只好打个表了QAQ)

时间: 2024-10-07 18:55:15

BZOJ3944 Sum的相关文章

【BZOJ3944/4805】Sum/欧拉函数求和 杜教筛

[BZOJ3944]Sum Description Input 一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问 Output 一共T行,每行两个用空格分隔的数ans1,ans2 Sample Input 6 1 2 8 13 30 2333 Sample Output 1 1 2 0 22 -2 58 -3 278 -3 1655470 2 题解: 粘自http://blog.csdn.net/skywalkert/article/details/

LeetCode OJ - Sum Root to Leaf Numbers

这道题也很简单,只要把二叉树按照宽度优先的策略遍历一遍,就可以解决问题,采用递归方法越是简单. 下面是AC代码: 1 /** 2 * Sum Root to Leaf Numbers 3 * 采用递归的方法,宽度遍历 4 */ 5 int result=0; 6 public int sumNumbers(TreeNode root){ 7 8 bFSearch(root,0); 9 return result; 10 } 11 private void bFSearch(TreeNode ro

129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

Leetcode 494 Target Sum 动态规划 背包+滚动数据

这是一道水题,作为没有货的水货楼主如是说. 题意:已知一个数组nums {a1,a2,a3,.....,an}(其中0<ai <=1000(1<=k<=n, n<=20))和一个数S c1a1c2a2c3a3......cnan = S, 其中ci(1<=i<=n)可以在加号和减号之中任选. 求有多少种{c1,c2,c3,...,cn}的排列能使上述等式成立. 例如: 输入:nums is [1, 1, 1, 1, 1], S is 3. 输出 : 5符合要求5种

31.SUM() 函数

SUM() 函数 SUM 函数返回数值列的总数(总额). SQL SUM() 语法 SELECT SUM(column_name) FROM table_name SQL SUM() 实例 我们拥有下面这个 "Orders" 表: O_Id OrderDate OrderPrice Customer 1 2008/12/29 1000 Bush 2 2008/11/23 1600 Carter 3 2008/10/05 700 Bush 4 2008/09/28 300 Bush 5

1305 Pairwise Sum and Divide

基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 有这样一段程序,fun会对整数数组A进行求值,其中Floor表示向下取整: fun(A) sum = 0 for i = 1 to A.length for j = i+1 to A.length sum = sum + Floor((A[i]+A[j])/(A[i]*A[j])) return sum 给出数组A,由你来计算fun(A)的结果.例如:A = {1, 4, 1},fun(A) = [5/4] + [

Java [Leetcode 303]Range Sum Query - Immutable

题目描述: Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. Example: Given nums = [-2, 0, 3, -5, 2, -1] sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3 Note: You may assume that the ar

LeetCode 303. Range Sum Query - Immutable

求数组nums[i,j]的和 思路:另开一sum数组,sum[i]为nums[0,i]的和,所以nums[i,j] = sum[j] - sum[i-1] 1 class NumArray { 2 public: 3 vector<int> sum; 4 NumArray(vector<int> &nums) { 5 sum.resize(nums.size(), 0); 6 sum[0] = nums[0]; 7 int len = nums.size(); 8 for(

【数组】Minimum Path Sum

题目: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 思路: 设res[i][j]表示从左上角到grid[i][