Gym 100541 B. Sum 分块的技巧、思维题、Interesting

I - I
Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u
Submit  Status  Practice  Gym 100541B

Description

standard input/output 

Write a program to compute the following sum S given a positive integer n:

, where  is the largest integer not greater than x.

Input

The input file consists of several datasets. The first line of the input file contains the number of datasets which is a positive integer 

and is not greater than 30. The following lines describe the datasets.

Each dataset contains a positive integer n(n ≤ 1012) written on a separate line.

Output

For each dataset, write in one line the remainder of the computed sum S divided by 106.

Sample Input

Input
2
1
5
Output
1
10

Source

UESTC 2016 Summer Training #13 Div.2

Gym 100541B


My Solution

写几个n试试看, 会有连续的数字出现, 

比如

n == 5, 5 2 1 1 1

n == 8, 8 4 2 2 1 1 1 1

相当于把这些数据分成好多块, 最多sqrt(n)份,区别于数据结构分块的另外一种分块吧^_^

len 表示相同数字的个数, 然后i表示这些相同val (LL)的第一个数的下标, 

ans + len*val //然后注意每一步取模

i += len; //直接跳到下一种val的第一个数

其中 len = n / val - i + 1


#include 
#include 
#include 
using namespace std;
typedef long long LL;
const int Hash = 1e6;

inline LL mod(LL x)
{
    return x - x/Hash*Hash;
}

int main()
{
    #ifdef LOCAL
    freopen("a.txt", "r", stdin);
    //freopen("b.txt", "w", stdout);
    #endif // LOCAL
    int T;
    LL n, val, len, ans;   //len 表示一串相同的 val 的长度
    scanf("%d", &T);
    while(T--){
        ans = 0;
        scanf("%I64d", &n);
        for(LL i = 1, j; i <= n; i += len){
            val = n/i;
            len = n/val - i + 1;
            ans = mod(ans + mod(len*val));
        }
        printf("%I64d\n", ans);

    }
    return 0;
}

  Thank you!

                                                                                                                                               ------from ProLights

你可能感兴趣的:(技巧☺☺,☺藏题阁☺,Gym,UESTC,2016,Summer,Training,思维题,算法的艺术)