D. Watch the Videos
抽象: 每个影片都是一条链子,我们预设每个影片下载完都需要单独看一下,即单独需要1分钟
我们的目标就是排序后二分一个合法的(check函数的目的就是判断是否合法)最长的子段的位置,这段子段可以合成一条链。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
using namespace std;
void solve()
{
int n, m;
cin >> n >> m;
vector<int> a(n + 1);
long long ans = n;//每个影片都是一条链子,我们预设每个影片下载完都需要单独看一下,即单独需要1分钟
for (int i = 1; i <= n; ++ i)
{
cin >> a[i];
ans += a[i];
}
sort(a.begin() + 1, a.end());
function<int(int)> check = [&](int x)//双指针遍历这段序列是否合法
{
int l = 1, r = x;
while ( l < r)
{
if (a[l] + a[r] > m) return 0;//这个不需要判断l<r,因为进入l++后进入下一轮循环的时候while会自动判断
r --;
if (l < r && a[l] + a[r] > m) return 0;//判断r--后是否合法
l ++ ;
}
return 1;
};
int l = 1, r = n;
while(l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
cout << ans - l + 1<< endl;//l包括l之前的所有影片都可以合并成一条链,但是这条链还是需要1分钟,因此最后补一个1
}
int32_t main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int T = 1;
// cin >> T;
while (T --) solve();
return 0;
}
D. Range = √Sum
推公式。。构造。。哎,不会推公式咋办,得多练了。
直接去看这篇博客吧,我应该写的没他好。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
using namespace std;
void solve()
{
int n;
cin >> n;
vector<int> a(n + 1);
if (n & 1)
{
for (int i = 1, j = n - n / 2 + 2; i <= n; ++ i)
{
a[i] = j ++;
}
a[1] -= 1; a[n] += 1; a[n - 1] += 1;
}
else
{
for (int i = 1, j = n - n / 2; i <= n; ++ i)
{
a[i] = j ++ ;
if (i == n / 2) j ++ ;
}
}
for (int i = 1; i <= n; ++ i) cout << a[i] << " ";
cout << endl;
}
int32_t main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int T = 1;
cin >> T;
while (T --) solve();
return 0;
}