AtCoder Beginner Contest 255 题解
只有 ABCDEFH 的题解。
A
模拟。
Code
const int N=10;
int n,m,a[N+10][N+10];
void mian(){
scanf("%d%d",&n,&m);
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
scanf("%d",a[i]+j);
printf("%d\n",a[n][m]);
}
B
二分答案,暴力判断是否可行。
Code
const int N=1000;
int n,k,a[N+10],x[N+10],y[N+10];
ll dis(int i,int j){
return 1LL*(x[i]-x[j])*(x[i]-x[j])+1LL*(y[i]-y[j])*(y[i]-y[j]);
}
bool check(ll r){
for(int i=1;i<=n;i++){
bool flg=0;
for(int j=1;j<=k;j++){
if(dis(i,a[j])<=r)flg=1;
}
if(!flg)return 0;
}
return 1;
}
void mian(){
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
scanf("%d",a+i);
for(int i=1;i<=n;i++)
scanf("%d%d",x+i,y+i);
ll l=0,r=1e18,ans=0;
while(l<=r){
ll mid=(l+r)>>1;
if(check(mid))ans=mid,r=mid-1;
else l=mid+1;
}
printf("%.6lf\n",std::sqrt(ans));
}
C
方便起见,如果 \(d<0\),则我们先把整个数列翻转一下。
分类讨论:\(x\le a_1\),\(x\ge a_n\),\(a_1\lt x\lt a_n\)。
Code
void mian(){
ll x,a,d,n;scanf("%lld%lld%lld%lld",&x,&a,&d,&n);
if(d<0){
a=a+(n-1)*d;
d=-d;
}
if(x<=a)printf("%lld\n",a-x);
else if(x>=a+(n-1)*d)printf("%lld\n",x-(a+(n-1)*d));
else{
if((x-a)%d==0)printf("%lld\n",0);
else{
ll k=(x-a)/d+1;
printf("%lld\n",std::min(x-(a+d*(k-1)),a+d*k-x));
}
}
}
D
要求的就是 \(\sum_{i=1}^n|a_i-x|\)。
先给 \(a\) 排序,每次询问二分“分界点”即可。
Code
const int N=2e5;
int n,m,a[N+10];
ll sum[N+10];
void mian(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
std::sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i];
while(m--){
int x;scanf("%d",&x);
if(x<=a[1])printf("%lld\n",sum[n]-1LL*n*x);
else if(x>=a[n])printf("%lld\n",1LL*n*x-sum[n]);
else{
int p=std::lower_bound(a+1,a+n+1,x)-a;
printf("%lld\n",1LL*(p-1)*x-sum[p-1]-1LL*(n-p+1)*x+(sum[n]-sum[p-1]));
}
}
}
E
观察一:如果确定了 \(a_1\sim a_n\) 中的某个数,那么整个 \(a\) 就确定了。
观察二:\(m\le 10\),可以枚举 \((i,j)\),计算当 \(a_i=x_j\) 时,\(a_1\) 应该是多少。同时此时的 \(a_1\) 给答案贡献了 \(1\)。
可以用 std::map 统计观察二中提到的贡献。
Code
const int N=1e5;
int n,m;
ll s[N+10],x[15],a[N+10];
std::map<ll,int> mp;
void mian(){
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
scanf("%lld",s+i);
for(int i=2;i<=n;i++)
a[i]=s[i-1]-a[i-1];
for(int i=1;i<=m;i++)
scanf("%lld",x+i);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(i&1)mp[x[j]-a[i]]++;
else mp[a[i]-x[j]]++;
}
int ans=0;
for(auto p:mp)
ans=std::max(ans,p.second);
printf("%d\n",ans);
}
F
初赛题……
以前一直都是在草稿纸上算,今天终于要在计算机上算了(
Code
const int N=2e5;
int n,a[N+10],b[N+10],pos[N+10],ptr;
int L[N+10],R[N+10];
int solve(int l,int r){
if(l==r){
if(pos[a[++ptr]]!=l){
puts("-1");
exit(0);
}
return a[ptr];
}
int rt=a[++ptr],p=pos[rt];
if(l<=p-1)L[rt]=solve(l,p-1);
if(p+1<=r)R[rt]=solve(p+1,r);
return rt;
}
void mian(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=1;i<=n;i++)
scanf("%d",b+i),pos[b[i]]=i;
if(a[1]!=1)return puts("-1"),void();
solve(1,n);
for(int i=1;i<=n;i++)
printf("%d %d\n",L[i],R[i]);
}
H
考虑哪些修改对某次询问有贡献,那我们要算的就是最后一次覆盖后的和,也就是总的和减去最后一次覆盖前的和。
可以用线段树维护区间最后被覆盖时的区间和 \(sum\),于是询问 \((d,l,r)\) 的答案为 \(d\left(\sum_{i=l}^ri\right)-sum\)。
Code
const int N=2e5;
const int P=998244353,inv=(P+1)/2;
struct Node{
ll sum,atag;
int ls,rs;
};
Node t[40000005];
ll n;
int m,tott,root;
ll calc(ll l,ll r){
return ((l+r)%P)*((r-l+1)%P)%P*inv%P;
}
#define ls(x) (t[x].ls)
#define rs(x) (t[x].rs)
void pushUp(int i){
t[i].sum=(t[ls(i)].sum+t[rs(i)].sum)%P;
}
void pushA(int i,ll l,ll r,ll atag){
t[i].sum=calc(l,r)*(atag%P)%P;
t[i].atag=atag;
}
void pushDown(int i,ll l,ll r){
if(t[i].atag){
ll mid=(l+r)>>1;
if(!ls(i))ls(i)=++tott;
if(!rs(i))rs(i)=++tott;
pushA(ls(i),l,mid,t[i].atag);
pushA(rs(i),mid+1,r,t[i].atag);
t[i].atag=0;
}
}
void modify(int &i,ll l,ll r,ll ql,ll qr,ll x){
if(!i)i=++tott;
if(ql<=l&&r<=qr)return pushA(i,l,r,x),void();
ll mid=(l+r)>>1;
pushDown(i,l,r);
if(ql<=mid)modify(ls(i),l,mid,ql,qr,x);
if(qr>mid) modify(rs(i),mid+1,r,ql,qr,x);
pushUp(i);
}
ll query(int i,ll l,ll r,ll ql,ll qr){
if(!i)return 0;
if(ql<=l&&r<=qr)return t[i].sum;
ll mid=(l+r)>>1,res=0;
pushDown(i,l,r);
if(ql<=mid)(res+=query(ls(i),l,mid,ql,qr))%=P;
if(qr>mid) (res+=query(rs(i),mid+1,r,ql,qr))%=P;
return res;
}
#undef ls
#undef rs
void mian(){
scanf("%lld%d",&n,&m);
while(m--){
ll d,l,r;
scanf("%lld%lld%lld",&d,&l,&r);
ll ans=calc(l,r)*(d%P)%P;
(ans-=query(root,1,n,l,r))%=P;
printf("%lld\n",(ans+P)%P);
modify(root,1,n,l,r,d);
}
}
本文来自博客园,作者:registerGen,转载请注明原文链接:https://www.cnblogs.com/registergen/p/abc255_solution.html

浙公网安备 33010602011771号