G. Hits Different
https://codeforces.com/problemset/problem/1829/G
dp:设求的值:n。设置数组val[n]为第n个的答案。那么有递推:val[n] = val[n-id[n]] + val[n-id[n]+1] - val[n-2*(id[n]-1)]
且以上均存在的情况下,id[n]表示第几层
采用离线算法,避免无用功。
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
#define IOS ios::sync_with_stdio(false), cin.tie(0) ,cout.tie(0)
using namespace std;
#define int unsigned long long
const int N = 1e6 + 10;
int val[N], id[N];
signed main()
{
IOS;
int t; cin >> t;
int maxn = 0;
queue<int>q;
while (t--)
{
int n; cin >> n;
maxn = max(maxn, n);
q.push(n);
}
int idx = 1;
int num = idx;
for(int i=1;i<=maxn;i++)
{
if (num == 0) { idx++; num = idx; }//记录id,每层有num个,如果清零那么idx增加,然后num从头开始
id[i] = idx;
val[i] += i * i;
if (id[i - id[i]] == id[i] - 1)val[i] += val[i - id[i]];
if (id[i - id[i] + 1] == id[i] - 1)val[i] += val[i - id[i] + 1];
if (i - (id[i] - 1) * 2 > 0 and id[i - (id[i] - 1) * 2] == id[i] - 2)val[i] -= val[i - (id[i] - 1) * 2];
num--;
}
while (!q.empty())
{
cout << val[q.front()] << '\n';
q.pop();
}
return 0;
}