hdu2058The sum problem(等差数列求和公式)
题目描述:
Given a sequence 1,2,3,......N, your job is to calculate all the possible sub-sequences that the sum of the sub-sequence is M.
思路:当然是滑动窗口啦,l,r不断移动,简单!
TLE....正解:观察区间的性质,是等差数列哒,所以某个区间的和可以表示为a+1,a+2,...a+d的和即找满足a*d+(d+1)*d/2=m的区间,
我们发现d^2是小于2*m的,于是我们就能枚举d,看求出的a是不是个整数,是整数说明就能找到一组区间,即[a+1,a+d],Orz...
滑动窗口TLE代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 100005; int main() { //freopen("test.txt", "r", stdin); bool f = 0; ll n, m; while (~scanf("%lld%lld", &n, &m)&&n) { if (f)printf("\n"); f = 1; ll l = 1, r = 1; ll sum = 1; while (r <= n) { if (l > m)break; while (sum < m) { r++; sum += r; } if (sum == m) { printf("[%lld,%lld]\n", l, r); sum -= l; l++; } while (sum > m) { sum -= l; l++; } } } return 0; }
等差求和公式AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 100005; int main() { int n, m; //freopen("test.txt", "r", stdin); while (~scanf("%d%d", &n, &m) && n) { int d, b,a; for (d = sqrt(2 * m); d >= 1; d--) { b = m - (1 + d) * d / 2; if (b % d == 0) {//看a是否是个正整数 a = b / d; printf("[%d,%d]\n", a + 1, a + d); } } printf("\n"); } return 0; }