KunOI Round 1 题解
A 唱
按照题意模拟即可。别见祖宗。
$\texttt{code}$
#include<bits/stdc++.h>
using namespace std;
int main(){
long long n,maxn=0;
cin>>n;
for(long long x,y;n--;){
cin>>x>>y;
maxn=max(maxn,x*y);
}
cout<<maxn;
}
B 跳
考虑当前石头是从哪里跳过来的,显然有状态转移方程 \(f_i=\min\limits_{j=i-k}^{i-1}(f_j+|a_i-a_j|)\),注意 \(j\) 的边界以及 \(f\) 的初始化 \(f_1=0\),其余为 \(\infty\)。别见祖宗。
扩展:若 \(n,k\) 同阶,考虑使用权值树状数组套动态开点线段树的方法,可以做到 \(\mathcal{O}(n\log^2n)\),就是要注意一下空间。
$\texttt{code}$
#include<bits/stdc++.h>
#define int long long
#define N 250005
using namespace std;
int n,k,a[N],f[N];
signed main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>a[i];
f[i]=1e18;
}
f[1]=0;
for(int i=2;i<=n;++i){
for(int j=max(i-k,1ll);j<i;++j){
f[i]=min(f[i],f[j]+abs(a[i]-a[j]));
}
}
cout<<f[n];
}
C rap
不难发现当 \(\gcd(i,j)=1\) 时,\(\text{rap}(i\cdot j)=\text{rap}(i)\cdot \text{rap}(j)\),类似于 \(\varphi\) 一样线性筛再预处理前缀和即可。
其实这个 \(\text{rap}\) 函数就是伟大的莫比乌斯 \(\mu\) 函数。
$\texttt{code}$
#include<bits/stdc++.h>
#define N 2500001
using namespace std;
int rap[N],l,r,T,p[N],sum[N];
bool no[N];
int main(){
p[1]=sum[1]=1;
for(int i=2;i<N;++i){
if(!no[i]){
rap[i]=-1;
p[++p[0]]=i;
}
for(int j=1;j<=p[0]&&i*p[j]<N;++j){
no[i*p[j]]=1;
if(!(i%p[j])){
rap[i*p[j]]=0;
break;
}
rap[i*p[j]]=-rap[i];
}
sum[i]=sum[i-1]+rap[i];
}
scanf("%d",&T);
while(T--){
scanf("%d%d",&l,&r);
printf("%d\n",sum[r]-sum[l-1]);
}
}
D 篮球
记 \((u,v,w)\) 为 \(u,v\) 之间有一条权值为 \(w\) 的边。 先建原图的双向边。
首先考虑没有改粉丝类型操作怎么做。套路地,第 \(i\) 种颜色建一个点 \(c_i\),连 \((u,c_{a_u},0)\) 和 \((c_{a_u},u,x)\)。答案即为 \(s\) 到每个点的最短路。
现在加上改粉丝类型的操作,可以类似地再建一个点 \(T\),连 \((c_i,T,y)\) 和 \((T,c_i,0)\)。答案即为 \(s\) 到每个点的最短路。
这里最短路使用的是 pb_ds pairing heap 优化的 Dijkstra,建议搭配 C++14(GCC 9) 使用。
$\texttt{code}$
#include<bits/stdc++.h>
#include<ext/pb_ds/priority_queue.hpp>
#define N 1000001
#define ll long long
using namespace std;
int n,m,s,k,a[N],tot,mp[N];
ll d[N],x,y;
bool vis[N];
struct edge{
int v;
ll w;
};
vector<edge>g[N];
struct node{
int v;
ll w;
bool operator<(const node&p)const{
return w>p.w;
}
};
__gnu_pbds::priority_queue<node>q;
int main(){
memset(d,0x3f,sizeof d);
scanf("%d%d%d%d%lld%lld",&n,&m,&s,&k,&x,&y);
tot=n;
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
for(int i=1,u;i<=k;++i){
scanf("%d",&u);
if(!mp[a[u]]){
g[mp[a[u]]=++tot].push_back({0,y});
g[0].push_back({tot,0});
}
g[u].push_back({mp[a[u]],0});
g[mp[a[u]]].push_back({u,x});
}
for(int u,v;m--;){
ll w;
scanf("%d%d%lld",&u,&v,&w);
g[u].push_back({v,w});
g[v].push_back({u,w});
}
q.push({s,d[s]=0});
while(q.size()){
auto[t,f]=q.top();
q.pop();
if(vis[t]){
continue;
}
vis[t]=1;
for(auto[v,w]:g[t]){
if(d[v]>f+w){
q.push({v,d[v]=f+w});
}
}
}
for(int i=1;i<=n;++i){
printf("%lld ",d[i]);
}
}
集贤亭
私信负责人,分享你独特的见解!
具体流程:写好博客,私信负责人链接,负责人看到会回复并展示在这个版块。贡献者会有每人一坤分的报酬,若提出了新奇/吊打标程等启发性见解,会酌情增加报酬。

浙公网安备 33010602011771号