E2
按值域分治的技巧
前置 : \(f(k , n) = 1 + k + k ^ 2 + ... + k ^ n\)
\(①\) : 假设答案最终的 \(n = 2\) , 对于 \(1 + k + k ^ 2\) , 我们在 \([2 , 10^9]\) 的范围二分 \(k\) 即可
\(②\) : 假设答案最终的 \(n > 2\) , 那么形式至少是 \(1 + k + k ^ 2 + k ^ 3\) , 由于 \(k ^ 3\) 的存在 , \(k\)的范围只能是 \([2 , 10^6]\) , 那么我们枚举 \(k\) , 对于每种 \(k\) , 递增枚举 \(n\) , 不断向 \(set\) 添加\(f(k , n)\) 的值 , 知道\(f(k , n) > 10^{18}\) , 由于指数增加 , 最终 \(set\) 中的个数为\(O(klogk) , k = 10^6\)
对于每个 \(x\) , 先尝试 \(①\) , 再尝试 \(②\) 即可
#include <bits/stdc++.h>
using ll = long long;
const ll INF = 1E18;
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::set<ll> p;
for(ll k = 2 ; k <= 1E6 ; ++k) {
ll w = 1 + k + k * k + k * k * k;
p.insert(w);
ll base = k * k * k;
while(true) {
if (base <= INF / k) {
base *= k;
}
else break;
if (w + base <= INF) {
w += base;
p.insert(w);
}
else break;
}
}
int t;
std::cin >> t;
while (t--) {
ll x ;
std::cin >> x;
ll l = 2 , r = 1E9;
while(l < r) {
ll mid = l + r >> 1;
if(1 + mid + mid * mid >= x) r = mid;
else l = mid + 1;
}
bool ok = false;
if(1 + r + r * r == x) {
ok = true;
}
if(!ok && p.count(x)) {
ok = true;
}
if(ok) std::cout << "YES\n";
else std::cout << "NO\n";
}
return 0;
}
F
策略 :
$① : $ 先尝试不删除(1次 或 2次) , 那么特殊物品的颜色对应个数会加一
$② : $ 将当前序列中不是这个颜色的删除
$③ : $ 如果特殊物品在 \(②\) 中变色 , 则找到位置 , 否则在尝试一次不删除 , 它必定变色
注意 : \(std::endl\) 可以直接刷新缓存区
#include <bits/stdc++.h>
using ll = long long;
void solve()
{
int n;
std::cin >> n;
std::vector<int> ar,Empty;
std::vector<int> cnt1(10 , 0) , cnt2(10 , 0);
for(int i = 0 ; i < n ; ++i) {
int x ; std::cin >> x;
cnt1[x] += 1;
}
auto query = [&](int n , std::vector<int> &q) {
std::cout << '-' << ' ' << q.size() ;
for(auto x : q) {
std::cout << ' ' << x + 1;
}
std::cout << std::endl;
std::vector<int> a(n - q.size());
for(int i = 0 ; i < n - q.size() ; ++i)
std::cin >> a[i];
return a;
};
ar = query(n , Empty);
for(int i = 0 ; i < ar.size() ; ++i)
cnt2[ar[i]] += 1;
int col = 0;
for(int i = 1 ; i <= 9 ; ++i) {
if(cnt2[i] == cnt1[i] + 1) {
col = i ; break;
}
}
if(col == 0) {
ar = query(n , Empty);
fill(cnt2.begin(),cnt2.end(),0);
for(int i = 0 ; i < ar.size() ; ++i)
cnt2[ar[i]]++;
for(int i = 1 ; i <= 9 ; ++i) {
if(cnt2[i] == cnt1[i] + 1) {
col = i ; break;
}
}
}
std::vector<int> del;
for(int i = 0 ; i < ar.size() ; ++i) {
if (ar[i] != col) {
del.push_back(i);
}
}
ar = query(ar.size() , del);
int ans = 0;
for(int i = 0 ; i < ar.size() ; ++i) {
if(ar[i] != col) {
ans = i + 1 ; break;
}
}
if(ans == 0) {
ar = query(ar.size() , Empty);
for(int i = 0 ; i < ar.size() ; ++i) {
if(ar[i] != col) {
ans = i + 1 ; break;
}
}
}
std::cout << "! " << ans << std::endl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
标签:883,std,int,ll,CF,++,ar,div3,size From: https://www.cnblogs.com/xqy2003/p/17537517.html