ABC343题解
前言:
E太毒瘤了,G先咕着。
A
题意
给定两个非负个位数
Sol
相加为
Code
#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define endl "\n"
#define fi first
#define se second
using namespace std;
const ll mod=1e9+7;
const ll inf=1e18;
const double eps=1e-6;
ll n,a[N];
string s;
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
cin>>s;
ll fl=0;
if((s[0]>='A'&&s[0]<='Z'))fl=1;
if(!fl){
cout<<"No\n";
return 0;
}
for(int i=1;i<s.size();i++){
if(s[i]<='z'&&s[i]>='a')continue;
cout<<"No\n";
return 0;
}
cout<<"Yes\n";
return 0;
}
B
题意
给定无向图的邻接矩阵(如果
Sol
Code
#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define endl "\n"
#define fi first
#define se second
using namespace std;
const ll mod=1e9+7;
const ll inf=1e18;
const double eps=1e-6;
ll n,m;
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
ll x;
cin>>x;
if(x)cout<<j<<" ";
}
cout<<endl;
}
return 0;
}
C
题意
找到最大的小于
Sol
直接枚举
Code
#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define endl "\n"
#define fi first
#define se second
using namespace std;
const ll mod=1e9+7;
const ll inf=1e18;
const double eps=1e-6;
ll n,m;
string s;
ll a[N];
ll ans=1;
void check(ll n){
ll p=n;
ll cnt=0;
while(n){
a[++cnt]=n%10;
n/=10;
}
for(int i=1,j=cnt;i<=j;i++,j--)if(a[i]!=a[j])return;
ans=p;
return ;
}
int main(){
cin>>n;
for(ll i=1;i;i++){
if(i*i*i>n){
cout<<ans<<endl;
break;
}
check(i*i*i);
}
return 0;
}
D
题意
Sol
开一个桶实时维护每个得分的人数,每次修改该得分人数的数量,如果人数减为
这里用了 set
,但其实用个变量维护就行。注意一开始全是
Code
#include<bits/stdc++.h>
#define ll long long
#define N 200005
#define endl "\n"
#define fi first
#define se second
using namespace std;
const ll mod=1e9+7;
const ll inf=1e18;
const double eps=1e-6;
ll n,m;
string s;
ll a[N],b[N],f[N];
map<ll,ll>mp;
set<ll>q;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)mp[0]++;
q.insert(0);
for(int i=1;i<=m;i++){
ll x,y;
cin>>x>>y;
mp[f[x]]--;
if(mp[f[x]]==0)q.erase(f[x]);
f[x]=f[x]+y;
if(mp[f[x]]==0)q.insert(f[x]);
mp[f[x]]++;
cout<<q.size()<<endl;
}
return 0;
}
E
题意
本场最答辩和恶心的题。
空间直角坐标系有三个边长为
报告任意符合题意的三个正方体的坐标或输出无解,要求坐标绝对值在
Sol
答辩暴力,几何,容斥题,以下分成三个部分来讲。
先规定一下,一个长方体,我们设它
暴力
由于是已知边长的正方体,所以只需要确定一个点就能确定所有点,直接枚举所有可能的端点坐标,复杂度是
首先考虑一个问题,对于一个合法的答案,我们可以将三个正方体视为一个整体,保持他们之间的相对位置不变,将他们整体随意平移到坐标系的任意位置,对答案毫无影响。
那我们不妨让其中一个正方体的一个端点位于原点,设这个正方体为
考虑其他两个正方体单独来说可能的位置,尽管他们仍然可能在空间中的任意位置,但对于本题来说,无非整体上就是两种:与
考虑离
然后如果和
几何
这部分主要是用来计算长方体重叠体积的。
先从一维的线段开始,两条线段什么时候有重叠部分?重叠部分如何表示?显然是(有个
二维呢?分开考虑:
三维呢?仍然分开考虑:
这样子,我们得到了两个长方体重叠部分的端点坐标。
三个长方体重叠的部分呢?先求两个长方体的重叠部分坐标,然后看作一个新的长方体,再和另一个取重叠部分。
如果没有重叠部分,让所有坐标都为
长方体计算体积就很简单了,
强烈建议把长方体封装进结构体。
容斥
简单三者容斥。
我们可以拿 举例。
规定一些名称:
图上应该以及很清楚了,不难得到等式:
算出来判断就行。
花了两个半小时写的题解,求关注qwq。
Code
#include<bits/stdc++.h>
#define ll long long
#define y1 yy
#define x1 xx
#define z1 zz
#define y2 yyy
#define x2 xxx
#define z2 zzz
#define y3 yyyy
#define x3 xxxx
#define z3 zzzz
#define N 200005
#define endl "\n"
#define fi first
#define se second
using namespace std;
const ll mod=1e9+7;
const ll inf=1e18;
const double eps=1e-6;
struct qwq{
ll sx,sy,sz;
ll ex,ey,ez;
ll v(){return abs((ex-sx)*(ey-sy)*(ez-sz));}
}A,B,C;
qwq cd(qwq n1,qwq n2){
ll sx=0,sy=0,sz=0;
ll ex=0,ey=0,ez=0;
if(!n1.v())return {sx,sy,sz,ex,ey,ez};
if(!n2.v())return {sx,sy,sz,ex,ey,ez};
if(n1.sx<=n2.sx&&n1.ex>=n2.sx)sx=n2.sx,ex=min(n1.ex,n2.ex);
if(n2.sx<=n1.sx&&n2.ex>=n1.sx)sx=n1.sx,ex=min(n1.ex,n2.ex);
if(n1.sy<=n2.sy&&n1.ey>=n2.sy)sy=n2.sy,ey=min(n1.ey,n2.ey);
if(n2.sy<=n1.sy&&n2.ey>=n1.sy)sy=n1.sy,ey=min(n1.ey,n2.ey);
if(n1.sz<=n2.sz&&n1.ez>=n2.sz)sz=n2.sz,ez=min(n1.ez,n2.ez);
if(n2.sz<=n1.sz&&n2.ez>=n1.sz)sz=n1.sz,ez=min(n1.ez,n2.ez);
return {sx,sy,sz,ex,ey,ez};
}
void sol(ll a,ll b,ll c){
A={0,0,0,7,7,7};
for(int x1=-7;x1<=7;x1++){
for(int y1=-7;y1<=7;y1++){
for(int z1=-7;z1<=7;z1++){
B={x1,y1,z1,x1+7,y1+7,z1+7};
qwq AB=cd(A,B);
for(int x2=-7;x2<=7;x2++){
for(int y2=-7;y2<=7;y2++){
for(int z2=-7;z2<=7;z2++){
C={x2,y2,z2,x2+7,y2+7,z2+7};
qwq AC=cd(A,C);
qwq BC=cd(B,C);
qwq ABC=cd(AB,C);
if(ABC.v()!=c)continue;
if(AC.v()+AB.v()+BC.v()-3*c!=b)continue;
if(A.v()+B.v()+C.v()-2*b-3*c!=a)continue;
cout<<"Yes\n";
cout<<A.sx<<" "<<A.sy<<" "<<A.sz<<" ";
cout<<B.sx<<" "<<B.sy<<" "<<B.sz<<" ";
cout<<C.sx<<" "<<C.sy<<" "<<C.sz<<" \n";
return ;
}
}
}
}
}
}
cout<<"No\n";
}
ll a,b,c;
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
cin>>a>>b>>c;
sol(a,b,c);
return 0;
}
F
题意
维护一个序列,支持单点修改,区间查询次大值出现次数。
Sol
经典特色线段树板题。
维护区间的最大值,次大值,最大值出现次数,次大值出现次数即可。
这样做是显然的,一个区间的最大值显然是两个子区间的最大值较大的那一个,一个区间的次大值,是两个子区间最大值较小的那一个,或者次大值最大的那一个,分类讨论一下即可。
Code
#include<bits/stdc++.h>
#define ll long long
#define N 800005
#define endl "\n"
#define fi first
#define se second
using namespace std;
const ll mod=1e9+7;
const ll inf=1e18;
const double eps=1e-6;
ll a[N],n;
namespace tr{
#define mid ((l+r)>>1)
#define ls (p<<1)
#define rs (p<<1|1)
//最大值,次大值,最大值出现次数,次大值出现次数。
struct qwq{
ll mx,my,nx,ny;
friend qwq operator+(const qwq &a,const qwq &b){
qwq c={0,0,0,0};
if(a.mx>b.mx){
c.mx=a.mx;
c.nx=a.nx;
if(b.mx>a.my){
c.my=b.mx;
c.ny=b.nx;
}
if(b.mx==a.my){
c.my=b.mx;
c.ny=b.nx+a.ny;
}
if(b.mx<a.my){
c.my=a.my;
c.ny=a.ny;
}
return c;
}
if(a.mx==b.mx){
c.mx=a.mx;
c.nx=a.nx+b.nx;
if(b.my>a.my){
c.my=b.my;
c.ny=b.ny;
}
if(b.my==a.my){
c.my=b.my;
c.ny=b.ny+a.ny;
}
if(b.my<a.my){
c.my=a.my;
c.ny=a.ny;
}
return c;
}
if(a.mx<b.mx){
c.mx=b.mx;
c.nx=b.nx;
if(b.my>a.mx){
c.my=b.my;
c.ny=b.ny;
}
if(b.my==a.mx){
c.my=b.my;
c.ny=b.ny+a.nx;
}
if(b.my<a.mx){
c.my=a.mx;
c.ny=a.nx;
}
return c;
}
}
}tr[N];
void build(ll p,ll l,ll r){
if(l==r){
tr[p].mx=a[l];
tr[p].my=0;
tr[p].nx=1;
tr[p].ny=0;
return ;
}
build(ls,l,mid);
build(rs,mid+1,r);
tr[p]=tr[ls]+tr[rs];
}
void upd(ll p,ll l,ll r,ll x,ll t){
if(l==r){
tr[p].mx=t;
tr[p].my=0;
tr[p].nx=1;
tr[p].ny=0;
return ;
}
if(x<=mid)upd(ls,l,mid,x,t);
if(x>mid)upd(rs,mid+1,r,x,t);
tr[p]=tr[ls]+tr[rs];
}
qwq qr(ll p,ll l,ll r,ll le,ll ri){
if(le<=l&&ri>=r)return tr[p];
if(le<=mid&&ri>mid)return qr(ls,l,mid,le,ri)+qr(rs,mid+1,r,le,ri);
if(le<=mid)return qr(ls,l,mid,le,ri);
if(ri>mid)return qr(rs,mid+1,r,le,ri);
return {0,0,0,0};
}
}
ll m=0;
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
tr::build(1,1,n);
while(m--){
ll op,x,y;
cin>>op>>x>>y;
if(op==1){
tr::upd(1,1,n,x,y);
}else cout<<tr::qr(1,1,n,x,y).ny<<endl;
}
return 0;
}
G
题意
Sol
Code
本文作者:yshpdyt
本文链接:https://www.cnblogs.com/yshpdyt/p/18049508
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步