暑假 D1 T1 新加密

来源:互联网 发布:淘宝visa卡怎样付款 编辑:程序博客网 时间:2024/06/05 06:18

【问题描述】
出题人Alice想告诉他的小伙伴小G两个数字。可这两个数字实在是太重要了,他必须要保证传递的这两个数字的绝对安全。终于有一天,他想到了一个绝妙的办法。我们先假设这两个数字为x,y,则其加密结果ans可以由下式得出:
ans=∑_(i=1)^x▒〖y mod i〗
其中a mod b表示a除以b的余数。
可是Alice没有电脑啊,他不能手算答案啊,因为x,y实在是太大了。于是你就看到了这个题目。
你不需要关心小G能否破解这个密码。

【输入】
输入文件为encode.in。
输入仅一行,为两个正整数x,y。

【输出】
输出文件为encode.out。
输出仅一行,表示加密的结果ans。

【输入输出样例1】
encode.in encode.out
20 13

119

50 % 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
0 0 2 2 0 2 1 2 5 0 6 2 11 8 5 2 16 14 12 10
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
8 6 4 2 0 24 23 22 21 20 19 18 17 16 15 14 13 12
39 40 41 42 43 44 45 46 47 48 49 50 51…… +∞
11 10 9 8 7 6 5 4 3 2 1 0 50,50,50……
发现:当i>50时 50%i=50
50>i>50/2时是公差为1的等差数列
我们再来关注从1~50/2的部分:
枚举1~√50(≈7),如上表,暴力算取模
例如:枚举2,50%2=0,50/2=25
枚举3,50%3=2,50/3=16
发现在17~25的这一段是公差为2的等差序列;(见上表)
枚举4,50%4=2,50/4=12
发现在13~16这一段是公差为3的等差序列;(见上表)
枚举5 50%5=0,50/5=10
发现在11~12这一段是公差为4的等差序列
枚举6 50%6=2 , 50/6=8
发现在9~10这一段是公差为5的等差序列
枚举7 50%7=1,50/7=7
发现8~8:(就一个数,我们想象一下如果被%的数比50还要大,那么应该是公差为6的等差数列,以此类推)

//此题你仍未掌握。 #include<cstdio>#include<iostream>using namespace std;const int bound = 1000010;int x, y;long long ans;int main(){    cin >> x >> y;    if(x <= bound){        for(int i = 1; i <= x; i++)            ans += y%i;        cout << ans << endl;        return 0;    }    if(x > y)   ans += (y-x)*y, x = y;    while(x > bound){        int now = y % x, t = y / x, pre = x;        x = y / (t + 1); int next = y % (x + 1);        ans += (long long)(now + next) * (pre - x) / 2;    }    for(int i = 1; i <= x; i++)            ans += y%i;    cout << ans << endl;    return 0;}
原创粉丝点击