[51NOD1087]1 10 100 1000(规律,二分)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1087

  用高中的数列知识就可以推出公式,不难发现f(n)=f(n-1)+n-1,f(1)=1。列出f(n)~f(2)的所有表达式,左右值分别求和就可以消去中间量,最后得出f(n)=(n*n-n)/2+1。

  刚才在上XML的时候一个同学告诉我,她初中数学老师告诉她假如数列的公差也是一个等差数列,那么这个式子一定表示为a*x^2+b*x+c的形式。我试着带进去了前三个值,卧曹还真是,学到了……

  对于本题,得到了公式,再二分优化一下即可。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <fstream>
 8 #include <cassert>
 9 #include <cstdio>
10 #include <bitset>
11 #include <vector>
12 #include <deque>
13 #include <queue>
14 #include <stack>
15 #include <ctime>
16 #include <set>
17 #include <map>
18 #include <cmath>
19 
20 using namespace std;
21 
22 typedef long long LL;
23 LL n;
24 
25 LL f(LL n) {
26     return (n * n - n) / 2 + 1;
27 }
28 
29 int main() {
30     // freopen("in", "r", stdin);
31     int T;
32     scanf("%d", &T);
33     while(T--) {
34         scanf("%I64d", &n);
35         bool flag = 0;
36         LL ll = 0, rr = n;
37         while(ll <= rr) {
38             LL mm = (ll + rr) >> 1;
39             LL val = f(mm);
40             if(val == n) {
41                 flag = 1;
42                 break;
43             }
44             else if(val > n) rr = mm - 1;
45             else ll = mm + 1;
46         }
47         printf("%d\n", flag);
48     }
49     return 0;
50 }

 

posted @ 2016-05-06 10:49  Kirai  阅读(269)  评论(0编辑  收藏  举报