文章目录
A.Maximum Increase
签到
B.Powers of Two
思路:预处理二进制,然后对每个数进行枚举即可。
C. Cellular Network
思路:看完题感觉一眼二分,考虑怎么写check,感觉check随便乱搞一下就过了,应该是双指针的check。
整体时间复杂度nlogn,注意开long long
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;
// #define endl "\n"
vector<int> a(N),b(N);
int n,m;
bool check(ll x)
{
int cnt=1;
ll l=b[cnt]-x;
ll r=b[cnt]+x;
for(int i=1;i<=n;i++){
while(cnt<=m&&(a[i]<l||a[i]>r)){
cnt++;
l=b[cnt]-x;
r=b[cnt]+x;
}
if(cnt>m) return false;
}
return true;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
ll l=0,r=2e9+5;
ll ans=-1;
while(l<=r){
ll mid=(l+r)/2;
if(check(mid)){
ans=mid;
r=mid-1;
}
else{
l=mid+1;
}
}
cout<<ans<<endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
t=1;
//cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
D. Road to Post Office
看到第一眼以为是dp,结果数字这么大,分析了一下感觉不涉及算法,就是简单的分类讨论即可,写完连样例都没过,然后改了改就行了。
思路:分类讨论,我们考虑走 k 千米两者所需要的时间:
汽车:
k
∗
a
+
t
k*a+t
k∗a+t
步行:
k
∗
b
k*b
k∗b
当我们步行k千米的代价小于开车时,我们只需要开一段车,即只使用一次汽车,不进行修理,剩余路程步行即可。
反之,我们对开车进行讨论,考虑对于最后一段路,是否应该修车,或者是直接步行即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 1e9+7;
const int maxv = 4e6 + 5;
// #define endl "\n"
void solve()
{
ll d,k,a,b,t;
cin>>d>>k>>a>>b>>t;
ll p=d%k;
ll ti=d/k;
ll ans=0;
ll f1=k*a+t,f2=k*b;
if(f1>f2){
ll ans=min(d,k)*a+max((d-k),0ll)*b;
//ans+=p*a;
cout<<ans<<endl;
}
else{
if(ti){
ll c1=ti*f1-t+p*b;
ll c2=ti*f1+p*a;
cout<<min(c1,c2)<<endl;
}
else{
cout<<p*a<<endl;
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
t=1;
//cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}
E. Analysis of Pathes in Functional Graph
第一眼以为是图,但题目说每个点只有一条出边,所以可以把他当作树,自然想到倍增,在倍增的过程中去维护信息即可。
倍增核心代码:
f
[
i
]
[
j
]
=
f
[
f
[
i
]
[
j
−
1
]
]
[
j
−
1
]
;
(
节点信息
)
s
u
m
[
i
]
[
j
]
=
s
u
m
[
i
]
[
j
−
1
]
+
s
u
m
[
f
[
i
]
[
j
−
1
]
]
[
j
−
1
]
;
(
权值和
)
m
h
[
i
]
[
j
]
=
m
i
n
(
m
h
[
i
]
[
j
−
1
]
,
m
h
[
f
[
i
]
[
j
−
1
]
]
[
j
−
1
]
)
;
(
最小值
)
\begin{align*} &f[i][j]=f[f[i][j-1]][j-1];(节点信息)\\ &sum[i][j]=sum[i][j-1]+sum[f[i][j-1]][j-1];(权值和)\\ &mh[i][j]=min(mh[i][j-1],mh[f[i][j-1]][j-1]);(最小值) \end{align*}
f[i][j]=f[f[i][j−1]][j−1];(节点信息)sum[i][j]=sum[i][j−1]+sum[f[i][j−1]][j−1];(权值和)mh[i][j]=min(mh[i][j−1],mh[f[i][j−1]][j−1]);(最小值)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> p3;
int mod = 998244353;
const int maxv = 4e6 + 5;
// #define endl "\n"
ll n,k;
ll f[N][40],sum[N][40];
int mh[N][40];
void query(int x)
{
ll tmp=k;
ll c1=0;
int c2=2e9;
for(int i=35;i>=0;i--){
if(tmp&(1ll<<i)){
tmp-=(1ll<<i);
c1+=sum[x][i];
c2=min(c2,mh[x][i]);
x=f[x][i];
}
}
cout<<c1<<" "<<c2<<endl;
}
void solve()
{
cin>>n>>k;
memset(mh,0x3f,sizeof mh);
for(int i=0;i<n;i++){
int x;
cin>>x;
f[i][0]=x;
}
for(int i=0;i<n;i++){
ll w;
cin>>w;
sum[i][0]=w;
mh[i][0]=w;
}
for(int j=1;j<40;j++){
for(int i=0;i<n;i++){
f[i][j]=f[f[i][j-1]][j-1];
sum[i][j]=sum[i][j-1]+sum[f[i][j-1]][j-1];
mh[i][j]=min(mh[i][j-1],mh[f[i][j-1]][j-1]);
}
}
for(int i=0;i<n;i++){
query(i);
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
t=1;
//cin>>t;
while(t--){
solve();
}
system("pause");
return 0;
}