CCPC 2022 网络赛 补题(不是题解)
Multiple set
注意到
l = (L + x - 1) / x;
r = R / x;
K = 2 ^ (r - l - 1) * (r + l) * (r - l + 1) * x;
枚举所有K的因数作为x check 即可,稍微优化一下枚举因数就行
点击查看代码
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int MAXN = 1e7;
ll prime[2000000], vis[MAXN + 10];
ll L,R,K;
void init() {
for (int i=2;i<=MAXN;i++) {
if (!vis[i]) prime[++prime[0]] = i;
for (int j = 1;j<=prime[0] && prime[j] * i <= MAXN; j++) {
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) break;
}
}
}
bool check(ll x) {
ll l = (L + x - 1) / x;
ll r = R / x;
if (r - l >60) return false;
// cout<<x<<' '<<l<<' '<<r<<'\n';
if (l==r) {
//cout<<(((r+l) * (r-l+1) * x) >> 1)<<' '<<K<<endl;
return ((r+l) * (r-l+1) * x) >> 1 == K;
}
return (((r+l) * (r-l+1) * x) << (r - l - 1)) == K;
}
void solve() {
cin>>L>>R>>K;
vector<ll> knum;
knum.push_back(1);
ll k = K;
for (int i=1;i<=prime[0] && prime[i] <= K;i++) {
ll p = 1;
queue<ll> add;
while (k%prime[i] == 0) {
k /= prime[i];
p *= prime[i];
for (int j=0;j<knum.size();j++) {
add.push(knum[j] * p);
}
}
while (!add.empty()) {
knum.push_back(add.front());
add.pop();
}
}
int num = 0;
vector<ll> ans;
for (int i=0;i<knum.size();i++) {
if (check(knum[i])) {
ans.push_back(knum[i]);
}
if (ans.size() > 100000) break;
}
if (ans.size() > 100000) {
cout<<"Too Many!\n";
} else if (ans.size() == 0) {
cout<<"No Solution\n";
} else {
cout<<ans.size()<<'\n';
for (int i=0;i<ans.size();i++) cout<<ans[i]<<' ';
cout<<'\n';
}
/*
x;
l = (L + x - 1) / x;
r = R / x;
K = 2 ^ (r - l - 1) * (r + l) * (r - l + 1) * x;
*/
}
int main() {
// ios::sync_with_stdio(false);
// cin.tie(0);
init();
int T;
cin>>T;
while (T--) solve();
return 0;
}
Transport Plan
很天才的想法,把直线拉到二维,在二维上维护 ans[i][j] //代表建立 (i,j) 传送门能使最终cost减少 ans[i][j]
然后考虑每一个运输计划 a,b,v 对它的贡献
ans[i][j] += v|a - b| - max(0, |a - b| - dis((a,b), (i,j))) //dis 是哈密顿距离
如图: 一个 v = 4 的贡献
点击查看代码
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
一次横向差分
1 -1
1 1 -1 -1
1 1 1 -1 -1 -1
1 1 1 1 -1 -1 -1 -1
1 1 1 -1 -1 -1
1 1 -1 -1
1 -1
二次横向差分
1 -2 1
1 0 -2 0 1
1 0 0 -2 0 0 1
1 0 0 0 -2 0 0 0 1
1 0 0 -2 0 0 1
1 0 -2 0 1
1 -2 1
二次横向 + 一次斜向差分
。。。
后面是两次斜向加一次纵向差分
最后能 O(1) 修改
只要能最后前缀和回去就行。。。
还有边界问题
。。。
不想补了hhh

浙公网安备 33010602011771号