题目链接:
题目大意:
给出一个数,问有哪些连续的区间的平方和能够得到这个数
题目分析:
定义三个量,l,r,sum
l代表当前的区间的左边界,r代表当前的区间的右边界,sum代表当前维护的区间的和,因为是自然数集中进行操作,所以元素师递增的,所以每次将r向前推进,然后如果当前的sum等于n,那么得到一个解,如果sum>n,因为后面的数添加进来只能导致sum原来越大,所以当前的l已经无解,所以l推进到sum <= n ,然后如果有解的话添加,然后重复上述步骤就可以了
代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long LL;
LL n;
struct Node
{
int l,r;
Node ( int a , int b )
{
l = a;
r = b;
}
bool operator < ( const Node & a ) const
{
return r-l > a.r - a.l;
}
};
vector<Node> v;
int main ( )
{
while ( ~scanf ( "%lld" , &n ))
{
v.clear();
LL l = 1,r = 0;
LL sum = 0;
while ( l*l <= n )
{
//cout << sum << endl;
bool flag = true;
// cout << l << " " << r << " " << sum << endl;
if ( r*r <= n )
{
r++;
sum += r*r;
if ( sum == n )
{
flag = false;
//cout << "YES : " << l << " " << r << endl;
v.push_back ( Node ( l , r ));
}
}
while ( sum > n )
{
sum -= l*l;
l++;
}
if ( sum == n && flag )
{
v.push_back ( Node ( l , r ) );
}
}
sort ( v.begin() , v.end() );
printf ( "%d\n" , v.size() );
for ( int i = 0 ; i < v.size() ; i++ )
{
printf ( "%d" , v[i].r - v[i].l+1 );
for ( int j = v[i].l ; j <= v[i].r ; j++ )
printf ( " %d" , j );
puts("");
}
}
}