2015ACM长春赛区网络赛C题

来源:互联网 发布:女人馒头蝴蝶 知乎 编辑:程序博客网 时间:2024/05/21 11:21

Aggregated Counting

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 677    Accepted Submission(s): 309


Problem Description
Aggregated Counting Meetup (ACM) is a regular event hosted by Intercontinental Crazily Passionate Counters (ICPC). The ICPC people recently proposed an interesting sequence at ACM2016 and encountered a problem needed to be solved.

The sequence is generated by the following scheme.
1. First, write down 1, 2 on a paper.
2. The 2nd number is 2, write down 2 2’s (including the one originally on the paper). The paper thus has 1, 2, 2 written on it.
3. The 3rd number is 2, write down 2 3’s. 1, 2, 2, 3, 3 is now shown on the paper.
4. The 4th number is 3, write down 3 4’s. 1, 2, 2, 3, 3, 4, 4, 4 is now shown on the paper.
5. The procedure continues indefinitely as you can imagine. 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, . . . .

The ICPC is widely renowned for its counting ability. At ACM2016, they came up with all sorts of intriguing problems in regard to this sequence, and here is one: Given a positive numbern, First of all, find out the position of the last n that appeared in the sequence. For instance, the position of the last 3 is 5, the position of the last 4 is 8. After obtaining the position, do the same again: Find out the position of the last (position number). For instance, the position of the last 3 is 5, and the position of the last 5 is 11. ICPC would like you to help them tackle such problems efficiently.

 

Input
The first line contains a positive integer T,T2000, indicating the number of queries to follow. Each of the following T lines contain a positive number n(n109) representing a query.
 

Output
Output the last position of the last position of each queryn. In case the answer is greater than 1000000006, please modulo the answer with 1000000007.
 

Sample Input
3310100000
 

Sample Output
11217507231491
 
找规律
1223344455566667777888899999.。。。
用a[i]表示整个数列的第i个数字,代表a[a[i]]有i个
规律找出来了但是还是没懂怎么写,先贴出别人写的代码等懂了再回来补起来
#include <cstdio>#define ll long long#define mod 1000000007using namespace std;int ans[500000];int post[500000];int tp;ll cal(ll a)//找∑(1~a){return a & 1 ? (a + 1) / 2 * a : a / 2 * (a + 1);}int binsearch(int l, int r, int x)//二分找第一个大于等于x的区间{int ans;while (l <= r){int mid = (l + r) >> 1;if (x <= post[mid]){ans = mid;r = mid - 1;}else l = mid + 1;}return ans;}int main(){post[1] = 1;ans[1] = 1;post[2] = 3;ans[2] = 5;tp = 3;for (int i = 2, j = 3; i < tp; ++i){while (j <= post[i] && post[tp - 1] < 1000000000)//n <= 1e9 所以只需找到post[tp] <= 1e9即可 i影响区间[j,post[i]]{post[tp] = post[tp - 1] + i;++j;++tp;}ans[i] = (ans[i - 1] + (((cal(post[i]) - cal(post[i - 1])) % mod)*i) % mod) % mod;//ans[i] = ans[i-1] + (∑(1~post[i])-∑(1~post[i]))*i}int t, n, id;scanf("%d", &t);while (t--){scanf("%d", &n);id = binsearch(1, tp - 1, n);//二分找到第一个大于等于n的区间printf("%d\n", (ans[id] - ((cal(post[id]) - cal(n))*id) % mod + mod) % mod);//ans[i] - (∑(1~post[i])-∑(1~n)) 即为n对应的答案}return 0;}


0 0
原创粉丝点击