题目链接: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 ", flag); 48 } 49 return 0; 50 }