【题解】Atcoder Beginner Contest 437(ABC437) A~F
A - Feet
直接代入计算。
#include<bits/stdc++.h>
using namespace std;
int a,b;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>a>>b;
cout<<a*12+b;
return 0;
}
B - Tombola
直接模拟即可。
#include<bits/stdc++.h>
using namespace std;
int h,w,n,ans;
int a[110][110],cnt[110];
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>h>>w>>n;
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++) cin>>a[i][j];
}
for(int i=1;i<=n;i++){
int q;
cin>>q;
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
if(a[i][j]==q){
cnt[i]++;
break;
}
}
}
}
for(int i=1;i<=n;i++) ans=max(ans,cnt[i]);
cout<<ans;
return 0;
}
C - Reindeer and Sleigh 2
考虑所有鹿都在雪橇上时,总重量为 \(\sum w_i\),换下第 \(i\) 个鹿,拉力 \(+p_i\),重量 \(-w_i\)。
题目要求拉力 \(\ge\) 重力,即总重量 \(-\) 拉力 \(\le0\)。根据刚才推得,换下第 \(i\) 个鹿,总重量 \(-\) 拉力变小 \(w_i+p_i\),则按 \(w_i+p_i\) 从大到小选择拉雪橇的鹿直到该值 \(\le 0\) 即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+10;
int T,n,sum,ans;
int w[N],p[N],a[N];
bool cmp(int x,int y){
return x>y;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>T;
while(T--){
cin>>n;
sum=ans=0;
for(int i=1;i<=n;i++){
cin>>w[i]>>p[i];
a[i]=p[i]+w[i];
sum+=w[i];
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
if(sum<=0) break;
ans++;
sum-=a[i];
}
cout<<n-ans<<'\n';
}
return 0;
}
D - Sum of Differences
先考虑没有绝对值怎么做。对于每个 \(a_i\),都要加 \(m\) 次并减去整个 \(b\) 序列的和 \(\sum b_j\),累加统计答案即可。
接着考虑加上绝对值,则对于 \(>a_i\) 的 \(b_j\),需要取相反数。二分查找 \(b\) 中 \(\le a_i\) 的位置 \(k\),维护 \(b\) 的前缀和,则对于 \(a_i\),其贡献为 \(k\times a_i-sumb_k+sumb_m-sumb_k-(m-k)\times a_i\)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+10;
const int p=998244353;
int n,m,ans;
int a[N],b[N];
int sumb[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
sort(b+1,b+1+m);
for(int i=1;i<=m;i++) sumb[i]=sumb[i-1]+b[i];
for(int i=1;i<=n;i++){
int t=upper_bound(b+1,b+1+m,a[i])-b-1;
int res=(a[i]*t-2*sumb[t]+sumb[m]-a[i]*(m-t))%p;
ans=(ans+res)%p;
}
cout<<ans;
return 0;
}
E - Sort Arrays
向已有序列后接元素形成新序列,不难想到字典树。按字典序排列即字典树的先序遍历,其中同一层的节点按字典序排列。
接着考虑同一大小的元素,如何让其按给定顺序输出。可以把这些元素合并为一个节点,同时维护每个节点包含的编号,按顺序排列。
使用 map 维护每个节点的出边,以及 vector 维护每个节点包含的编号。
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int n;
int h[N],tot=1;
int a[N],b[N];
map<int,int> G[N];
vector<int> unq[N];
void dfs(int u){
for(int i=0;i<unq[u].size();i++) cout<<unq[u][i]<<' ';
for(auto i:G[u]) dfs(i.second);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
h[0]=1;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
int u,v;
u=h[a[i]];
if(!G[u].count(b[i])) G[u][b[i]]=++tot;
v=G[u][b[i]];
h[i]=v,unq[v].push_back(i);
}
dfs(1);
return 0;
}
F - Manhattan Christmas Tree 2
定义两点间曼哈顿距离:\(|x_1-x_2|+|y_1-y_2|\)。因此查询点 \((x,y)\) 和某一点 \(i\) 间的曼哈顿距离为 \(|x-X_i|+|y-Y_i|\)。
因为绝对值较难维护,所以考虑把绝对值拆掉。
分开考虑前后两个绝对值:\(|x-X_i|=\max(x-X_i,-x+X_i),|y-Y_i|=\max(y-Y_i,-y+Y_i)\)。
合并两个最大值得到原式:\(|x-X_i|+|y-Y_i|=\max((x+y)-(X_i+Y_i),(x-y)-(X_i-Y_i),(-x+y)+(X_i-Y_i),(-x-y)+(X_i+Y_i))\)。
然后我们就可以开线段树维护 \(X_i\pm Y_i\) 的区间最值了,减法需要区间最小值,加法需要区间最大值。查询时计算出以上四个式子,找最大值。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
const int INF=1e18;
int n,q;
int X[N],Y[N];
struct Node{
int mx1,mx2;
int mn1,mn2;
int l,r;
};
struct Segtr{
Node tr[4*N];
void push_up(int p){
tr[p].mx1=max(tr[2*p].mx1,tr[2*p+1].mx1);
tr[p].mx2=max(tr[2*p].mx2,tr[2*p+1].mx2);
tr[p].mn1=min(tr[2*p].mn1,tr[2*p+1].mn1);
tr[p].mn2=min(tr[2*p].mn2,tr[2*p+1].mn2);
}
void build(int p,int l,int r){
tr[p].l=l,tr[p].r=r;
if(l==r){
tr[p].mx1=tr[p].mn1=X[l]+Y[l];
tr[p].mx2=tr[p].mn2=X[l]-Y[l];
return ;
}
int mid=(l+r)/2;
build(2*p,l,mid);
build(2*p+1,mid+1,r);
push_up(p);
}
void update(int p,int u,int x,int y){
if(tr[p].l==tr[p].r&&tr[p].l==u){
X[u]=x,Y[u]=y;
build(p,tr[p].l,tr[p].r);
return ;
}
int mid=(tr[p].l+tr[p].r)/2;
if(u<=mid) update(2*p,u,x,y);
else update(2*p+1,u,x,y);
push_up(p);
}
int query(int p,int l,int r,int x,int y){
int val=-INF;
if(l<=tr[p].l&&tr[p].r<=r){
val=max(val,x+y-tr[p].mn1);
val=max(val,x-y-tr[p].mn2);
val=max(val,-x-y+tr[p].mx1);
val=max(val,-x+y+tr[p].mx2);
return val;
}
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid) val=max(val,query(2*p,l,r,x,y));
if(r>mid) val=max(val,query(2*p+1,l,r,x,y));
return val;
}
}seg;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>X[i]>>Y[i];
seg.build(1,1,n);
while(q--){
int op;
cin>>op;
if(op==1){
int u,x,y;
cin>>u>>x>>y;
seg.update(1,u,x,y);
}else{
int l,r,x,y;
cin>>l>>r>>x>>y;
cout<<seg.query(1,l,r,x,y)<<'\n';
}
}
return 0;
}

浙公网安备 33010602011771号