AtCoder Beginner Contest 253 题解
作者:互联网
二模考完了,打场比赛放松身心。
比赛地址:https://atcoder.jp/contests/abc253。
只有 ABCDEF 的题解,G 待补,H 不会。
A
模拟。
Code
void mian(){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a<=b&&b<=c||c<=b&&b<=a)puts("Yes");
else puts("No");
}
B
还是模拟。
Code
void mian(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%s",s[i]+1);
int x1=-1,y1=-1,x2=-1,y2=-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]=='o'){
if(x1==-1)x1=i,y1=j;
else x2=i,y2=j;
}
printf("%d\n",std::abs(x1-x2)+std::abs(y1-y2));
}
C
又是模拟。
Code
void mian(){
int m;scanf("%d",&m);
std::multiset<int> s;
while(m--){
int opt,x,y;scanf("%d",&opt);
if(opt==1)scanf("%d",&x),s.insert(x);
if(opt==2){
scanf("%d%d",&x,&y);
for(int i=1;i<=y;i++){
auto it=s.find(x);
if(it==s.end())break;
s.erase(it);
}
}
if(opt==3){
printf("%d\n",*(--s.end())-*(s.begin()));
}
}
}
D
小学奥数容斥原理。
Code
ll sum(ll x){
return 1LL*x*(x+1)/2;
}
void mian(){
ll n,a,b;
scanf("%lld%lld%lld",&n,&a,&b);
ll lcm=a/std::__gcd(a,b)*b;
printf("%lld\n",sum(n)-a*sum(n/a)-b*sum(n/b)+(lcm)*sum(n/lcm));
}
E
dp。设 \(f_{i,j}\) 表示考虑前 \(i\) 项且 \(a_i=j\) 时的答案。则
\[f_{i,j}=\sum_{|j-l|\ge k}f_{i-1,l} \]显然可以通过对于每个 \(i\) 处理 \(f_{i,j}\) 的前缀和来优化。
注意特判 \(k=0\) 的情况!
Code
const int P=998244353;
const int N=5000;
int n,m,k,f[N+10][N+10],sum[N+10][N+10];
void mian(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++)f[1][i]=1,sum[1][i]=(sum[1][i-1]+1)%P;
for(int i=2;i<=n;i++){
if(k){
for(int j=1;j<=m;j++){
if(j-k>=1)(f[i][j]+=sum[i-1][j-k])%=P;
if(j+k<=m)(f[i][j]+=(sum[i-1][m]-sum[i-1][j+k-1])%P)%=P;
}
}else{
for(int j=1;j<=m;j++)
(f[i][j]+=sum[i-1][m])%=P;
}
for(int j=1;j<=m;j++)
sum[i][j]=(sum[i][j-1]+f[i][j])%P;
}
int ans=0;
for(int i=1;i<=m;i++)
(ans+=f[n][i])%=P;
printf("%d\n",(ans%P+P)%P);
}
F
这题出的不错。
考虑对于一个询问 \((x,y)\),什么修改操作对它有贡献。
那显然是离它最近且修改的是第 \(x\) 行的那个操作 \(2\) 和这个操作 \(2\) 之后,所有涉及到第 \(y\) 列的操作 \(3\)。
前者开 \(n\) 个 std::vector
维护即可。
对于后者,本质上是有两个轴:时间轴和列轴。这样一来,我们可以以时间轴为要被可持久化的轴,建一棵可持久化线段树,维护区间加、单点查。注意要开标记永久化。
Code
#include<algorithm>
#include<cstdio>
#include<vector>
typedef long long ll;
const int N=2e5;
struct Node{
ll v,lt;
int ls,rs;
};
int n,m,q;
Node t[N<<6];
int rt[N+10],cnt;
std::vector<std::pair<int,int>> vec[N+10];
#define ls(x) (t[x].ls)
#define rs(x) (t[x].rs)
void pushUp(int i,int l,int r){
int mid=(l+r)>>1;
t[i].v=t[ls(i)].v+t[rs(i)].v+t[ls(i)].lt*(mid-l+1)+t[rs(i)].lt*(r-mid);
}
void modify(int& i,int j,int l,int r,int ml,int mr,int d){
i=++cnt;
t[i].v=t[j].v,t[i].lt=t[j].lt;
ls(i)=ls(j),rs(i)=rs(j);
if(ml<=l&&r<=mr){
t[i].lt+=d;
return;
}
int mid=(l+r)>>1;
if(ml<=mid)modify(ls(i),ls(j),l,mid,ml,mr,d);
if(mr>mid) modify(rs(i),rs(j),mid+1,r,ml,mr,d);
pushUp(i,l,r);
}
ll query(int i,int l,int r,int ql,int qr){
if(ql==l&&r==qr)return t[i].v+t[i].lt*(r-l+1);
int mid=(l+r)>>1;
ll tag=(qr-ql+1)*t[i].lt;
if(ql>mid) return tag+query(rs(i),mid+1,r,ql,qr);
if(qr<=mid)return tag+query(ls(i),l,mid,ql,qr);
return tag+query(ls(i),l,mid,ql,mid)+query(rs(i),mid+1,r,mid+1,qr);
}
#undef ls
#undef rs
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)vec[i].push_back({1,0});
for(int i=1;i<=q;i++){
int opt,l,r,x,y;
scanf("%d",&opt);
if(opt==1){
scanf("%d%d%d",&l,&r,&x);
modify(rt[i],rt[i-1],1,m,l,r,x);
}
if(opt==2){
scanf("%d%d",&l,&x);
rt[i]=rt[i-1];
vec[l].push_back({i,x});
}
if(opt==3){
scanf("%d%d",&x,&y);
rt[i]=rt[i-1];
std::pair<int,int> qwq=vec[x].back();
int t=qwq.first,x0=qwq.second;
ll sum=query(rt[i],1,m,y,y)-query(rt[t-1],1,m,y,y);
printf("%lld\n",x0+sum);
}
}
}
标签:AtCoder,rs,int,题解,sum,scanf,lt,253,ll 来源: https://www.cnblogs.com/registergen/p/abc253_solution.html