995 字
4 分钟
ABC 467
2026-07-24

A. Obesity#

给定 WeightWeightHeightHeight,BMI 的计算公式是 BMI=Weight(kg)÷Height(cm)÷Height(cm)BMI=Weight(kg) \div Height(cm)\div Height(cm),超重的标准是 BMI25BMI\geq 25,问是否超重。

注意给的 HHcmcm。。。

signed main(){
int h,w;cin>>h>>w;
if(w*100*100>=25*h*h)cout<<"Yes\n";
else cout<<"No\n";
return 0;
}

B. Keep the Change#

NN 家商店,在 ithi\text{th} 家商店购买了价值 AiA_{i} 的商品,支付了 Bi(BiAi)B_i(B_{i}\geq A_{i})。 若 Si=S_i= keep,则不收零钱,若 Si=S_i= take,则收零钱。 问少收了多少零钱。

模拟。当 keep 时,给 ans 加上对应的 BiAiB_{i}-A_{i} 即可。

signed main(){
int n;cin>>n;
int ans=0;
for(int i=0;i<n;i++){
int a,b;string s;
cin>>a>>b>>s;
if(s=="take")continue;
else ans+=(b-a);
}
cout<<ans<<endl;
return 0;
}

C. Adjacent Sums (easy)#

给定由 0011 组成的长度为 NN 的数组 AA 和长度为 N1N-1 的数组 BB。 每次操作可以选择 1iN1\leq i\leq N,使得 Ai=Ai+1A_i=A_{i}+1。 问最少多少次操作可以满足对于所有 1iN11\leq i\leq N-1,有 (Ai+Ai+1)Bi(mod2)(A_{i}+A_{i+1})\equiv B_{i}\pmod 2

(Ai+Ai+1)Bi(mod2)    AiAi+1=Bi(A_{i}+A_{i+1})\equiv B_{i}\pmod 2 \implies A_{i}\oplus A_{i+1}=B_{i} 所以对于确定的 A0A_0BB,可以得到整个目标 AA。 计算当 A0=0A_0=0A0=1A_0=1 时需要的操作数,取较小值即可。

signed main(){
int n,m;cin>>n>>m;
vector<int> a(n),b(n-1),pre(n);
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n-1;i++)cin>>b[i];
for(int i=1;i<n;i++)pre[i]=pre[i-1]^b[i-1];
int ans0=0,ans1=0;
for(int i=0;i<n;i++){
if(a[i]!=pre[i])ans0++;
if(a[i]!=1^pre[i])ans1++;
}
cout<<min(ans0,ans1)<<endl;
return 0;
}

D. Concentric Circles#

给定四个点 P,Q,R,SP,Q,R,S,问是否有两个圆 C1C_{1}C2C_2(两个圆可以重合),满足:

  • P,QP,Q 位于 C1C_1 的圆周上。
  • R,SR,S 位于 C2C_2 的圆周上。
  • C1C_1C2C_2 有相同的圆心。

计算几何会回报每一个踏踏实实推式子的人 🤗。C1C_1 的圆心位于 P,QP,Q 的中垂线上,C2C_2 的圆心位于 R,SR,S 的中垂线上,两圆若有相同圆心,则必定位于两中垂线交点处。 具体求中垂线以及交点方法见代码。

#define int __int128
struct line{
int a,b,c;
line(int a,int b,int c):a(a),b(b),c(c){}
};
line getline(pair<int,int> p1,pair<int,int> p2){
int x1=p1.first,x2=p2.first,y1=p1.second,y2=p2.second;
int dx=x2-x1,dy=y2-y1;
int a=2*dx,b=2*dy;
int c=-dx*(x1+x2)-dy*(y1+y2);
return line(a,b,c);
}
void solve(){
pair<signed,signed> p,q,r,s;
cin>>p.first>>p.second>>q.first>>q.second;
cin>>r.first>>r.second>>s.first>>s.second;
line l1=getline(p,q),l2=getline(r,s);
if(l1.a*l2.b-l2.a*l1.b!=0){
cout<<"Yes\n";
return;
}
if((l1.a*l2.c==l2.a*l1.c)&&(l1.b*l2.c==l2.b*l1.c))cout<<"Yes\n";
else cout<<"No\n";
}

F.Email Scheduling Optimization#

给定两个长度为 NN 的正整数序列 AABB。以及 QQ 次操作。每个操作可以将 AABB 中的一个元素更改为指定值。 每次操作后问如下问题:给 NN 家公司发送邮件并收回复。向 jthj\text{th} 家公司发送花费 AjA_j 分钟,回复在发送后 BjB_j 分钟到达。 同一时间只能写一封邮件,问收发这 NN 封邮件花费的最短时间。

先考虑子问题。由于同一时间只能写一封邮件而可以等待多封不同邮件,显然按照 BiB_{i} 降序排列最优。 接下来的问题就是:动态修改 AiA_iBiB_i 后,维护按 BB 降序排列时的 max(j=1iAj+Bi)\text{max}\left( \sum_{j=1}^iA_{j} +B_{i}\right)

考虑使用线段树。 由于 Bi109B_{i}\leq 10^9N+Q2×105N+Q\leq 2\times10^5,所以要离散化 BB 后构造线段树。先读入所有可能的 BiB_{i} 后,降序排序去重 BB 得到线段树的大小。 对于任意 BB 值,维护 sumA=Bj=BAj,maxVal=sumA+BsumA=\sum_{B_{j}=B} A_{j},maxVal=sumA+B。而最终答案就是根节点的 maxValmaxVal

合并节点 lr 时,易得,sumA 的取值应该为 l.sumA+r.sumAl.sumA+r.sumAmaxVal 的取值应该为 max(l.maxVal,l.sumA+r.maxVal)\text{max}(l.maxVal,l.sumA+r.maxVal)。 当修改 AiA_ixx 时,由于 BiB_i 不变,只需要把本次修改的差值 xAix-A_{i} 加到对应的 BiB_isumAsumA 中即可。 当修改 BiB_ixx 时,则需要在原来的 BiB_isumAsumA 中减去当前的 AiA_i,再把当前的 AiA_i 加回到修改后的 xx 对应的 sumAsumA 中去。

class SegTree{
struct Node{
int sumA,maxVal;
Node():sumA(0),maxVal(-LLONG_MAX){}
Node(int s,int m):sumA(s),maxVal(m){}
};
int n,n4,root,end;
vector<Node> tree;
vector<int> revB;
vector<int> count;
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
Node merge(Node l,Node r){
return Node(l.sumA+r.sumA,max(l.maxVal,l.sumA+r.maxVal));
}
void build(int l,int r,int p){
if(l==r){
tree[p]=Node();
return;
}
int m=l+(r-l)/2;
build(l,m,ls(p));
build(m+1,r,rs(p));
tree[p]=merge(tree[ls(p)],tree[rs(p)]);
}
void update(int l,int r,int pos,int val,int cnt,int p){
if(l==r){
tree[p].sumA+=val;
count[l]+=cnt;
if(count[l]==0)tree[p].maxVal=-LLONG_MAX;
else tree[p].maxVal=tree[p].sumA+revB[l];
return;
}
int m=l+(r-l)/2;
if(pos<=m)update(l,m,pos,val,cnt,ls(p));
else update(m+1,r,pos,val,cnt,rs(p));
tree[p]=merge(tree[ls(p)],tree[rs(p)]);
}
public:
SegTree(int sz,vector<int> rb){
n=sz;
n4=n*4;
tree=vector<Node>(n4,Node());
count=vector<int>(n,0);
revB=rb;
root=1;
end=n-1;
build(0,end,root);
}
void update(int pos,int val,int cnt){
update(0,end,pos,val,cnt,root);
}
int getans(){
return tree[root].maxVal;
}
};
signed main(){
int n,q;cin>>n>>q;
vector<int> A(n),B(n);
vector<tuple<int,int,int>> qs(q);
vector<int> allB;
for(int i=0;i<n;i++)cin>>A[i];
for(int i=0;i<n;i++){
cin>>B[i];
allB.push_back(B[i]);
}
for(int i=0;i<q;i++){
int op,x,y;cin>>op>>x>>y;
x--;
qs[i]={op,x,y};
if(op==2) allB.push_back(y);
}
sort(allB.rbegin(),allB.rend());
allB.erase(unique(allB.begin(),allB.end()),allB.end());
int m=allB.size();
SegTree st(m,allB);
for(int i=0;i<n;i++)st.update(lower_bound(allB.begin(),allB.end(),B[i],greater<int>())-allB.begin(),A[i],1);
for(auto [op,i,x]:qs){
if(op==1){
int p=lower_bound(allB.begin(),allB.end(),B[i],greater<int>())-allB.begin();
st.update(p,x-A[i],0);
A[i]=x;
}else{
int oldp=lower_bound(allB.begin(),allB.end(),B[i],greater<int>())-allB.begin();
st.update(oldp,-A[i],-1);
B[i]=x;
int p=lower_bound(allB.begin(),allB.end(),B[i],greater<int>())-allB.begin();
st.update(p,A[i],1);
}
cout<<st.getans()<<endl;
}
return 0;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

ABC 467
https://leaf146.cn/posts/abc467
作者
LeAf146
发布于
2026-07-24
许可协议
MIT

部分信息可能已经过时