【题解】2023牛客寒假算法基础集训营2

news/2024/11/28 20:33:39/

目录

  • A. Tokitsukaze and a+b=n (easy)
    • 思路
  • B. Tokitsukaze and a+b=n (medium)
    • 思路
  • Tokitsukaze and a+b=n (hard)
    • 思路
  • D. Tokitsukaze and Energy Tree
    • 思路
      • bfs
      • dfs
  • E. Tokitsukaze and Energy Tree
    • 思维
  • F. Tokitsukaze and Gold Coins (easy)
    • 思路
  • G. Tokitsukaze and Gold Coins (hard)
  • H. Tokitsukaze and K-Sequence
    • 思路
  • I. Tokitsukaze and Musynx
    • 思路
  • J. Tokitsukaze and Sum of MxAb
    • 思路
  • K. Tokitsukaze and Synthesis and Traits
    • 思路
  • L. Tokitsukaze and Three Integers
    • 思路

A. Tokitsukaze and a+b=n (easy)

思路

tag: 枚举 暴力
数据范围很小,可以直接暴力。

int n;
void solve()
{cin>>n;int l1,r1,l2,r2;cin>>l1>>r1>>l2>>r2;int res=0;set<PII>s;rep(i,l1,r1)if(n-i>=l2&&n-i<=r2)s.insert({i,n-i});cout<<s.size()<<endl;
}

B. Tokitsukaze and a+b=n (medium)

思路

tag: 贪心,二分
这题相对于A在范围上进行了扩大,所以不能采用暴力做法,不难发现,当第一个区间选取的越靠右时,则在第二个区间选取就越靠左,反之也成立,此时题目就对应了二分的两种板子做法(当然此题也可以O(1)写,这里不在赘述。

int n;
void solve()
{cin>>n;map<int,int>mp;int l1,r1,l2,r2;cin>>l1>>r1>>l2>>r2;int l=l1-1,r=r1;while(l<r){int mid=l+r+1>>1;if(n-mid>=l2)l=mid;else r=mid-1;}int x=l;l=l1,r=r1+1;while(l<r){int mid=l+r>>1;if(n-mid<=r2)r=mid;else l=mid+1;}int y=r;cout<<x-y+1<<endl;
}

Tokitsukaze and a+b=n (hard)

思路

tag :二分,容斥,哈希
B求两个区间,此题给了很多区间,有多少种选法,满足:从
m 个区间中选择两个区间 。
此时在我们面前的有两个问题:1.区间修改 2.找a=b-n
区间修改这里可以采用差分数组解决,那么a=b-n则用哈希表来解决
当我们枚举a时,判断有多少个b-n即可。
此时注意一个细节,我们这样寻找a->n-b,有可能a和b在一个区间的,这种情况怎么去除?我们可以将在同一个区间满足a=n-b的情况全部累加,再全部减去即可。

int n,m;
const int N=4e5+10;
int d[N];
const int mod=998244353;
int get(int l1,int r1,int l2,int r2)
{int l=l1-1,r=r1;while(l<r){int mid=l+r+1>>1;if(n-mid>=l2)l=mid;else r=mid-1;}int x=l;l=l1,r=r1+1;while(l<r){int mid=l+r>>1;if(n-mid<=r2)r=mid;else l=mid+1;}int y=r;return x-y+1;
}
void solve()
{cin>>n>>m;int s=0;rep(i,1,m){int l,r;cin>>l>>r;s+=get(l,r,l,r);d[l]++,d[r+1]--;}int res=0;rep(i,1,N-1)d[i]+=d[i-1];rep(i,1,N-1){if(n>=i)res=(res+d[i]*d[n-i]);}res=(res-s+mod)%mod;cout<<res<<endl;
}

D. Tokitsukaze and Energy Tree

思路

tag:贪心,dfs,bfs,树形DP
贪心的想,当一个大的权值点深度越深,则它被求sum的次数就越多,所以我们就往这个方向靠,求出每个点的深度,深度越深,则赋予其越大的权值,最后累加求和即可。

bfs

int n;
const int N=2e5+10;
int h[N],ne[N<<1],e[N<<1],idx;
int dep[N],w[N];
void add(int a,int b)
{e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void bfs(int u)
{queue<int>q;q.push(u);dep[u]=1;while(q.size()){int sz=q.size();for(int i=0;i<sz;i++){auto t=q.front();q.pop();for(int i=h[t];~i;i=ne[i]){int j=e[i];dep[j]=dep[t]+1;q.push(j);}}} 
}
void solve()
{memset(h,-1,sizeof h);cin>>n;rep(i,2,n){int a;cin>>a;add(a,i);}rep(i,1,n)cin>>w[i];bfs(1);sort(w+1,w+1+n);sort(dep+1,dep+1+n);int res=0;rep(i,1,n)res+=dep[i]*w[i];cout<<res<<endl;
}

dfs

int n;
const int N=2e5+10;
int h[N],ne[N<<1],e[N<<1],idx;
int dep[N],w[N];
void add(int a,int b)
{e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int fa)
{dep[u]=dep[fa]+1;for(int i=h[u];~i;i=ne[i]){int j=e[i];if(j==fa)continue;dfs(j,u);}
}
void solve()
{memset(h,-1,sizeof h);cin>>n;rep(i,2,n){int a;cin>>a;add(a,i),add(i,a);}rep(i,1,n)cin>>w[i];dfs(1,0);sort(w+1,w+1+n);sort(dep+1,dep+1+n);int res=0;rep(i,1,n)res+=dep[i]*w[i];cout<<res<<endl;
}

E. Tokitsukaze and Energy Tree

思维

tag: 二分,数学,打表,找规律
在这里插入图片描述
均值不等式可得
由绝对值不等式可知,函数最小值在n\sqrt nn处,由于题目所求的是最小正整数,所以设g(x)是f(x)取整的函数,函数图像
在这里插入图片描述
可知我们的函数值在整数点的邻域内是保持不变的,所以此题我们求最小值并不能采用三分写法。但是二分可以啊(傲娇。
由于我们给的是一个固定的区间,所以我们求的最小值无非L,R,n\sqrt nn,⌈n⌉\lceil \sqrt n \rceiln,四种情况,我们找到最小值的点,应该函数值相等的邻域的左端点,所以我们用求最小值的二分模板来解决

int l,r,n;
int f(int x)
{return n/x+x-1;
}
void solve()
{cin>>n>>l>>r;int sqrt_n=sqrtl(n);int f_l=f(l);int f_r=f(r);int pos=l,minv=f(l);if(f_l>f_r){pos=r;minv=f(r);}if(sqrt_n>=l&&sqrt_n<=r&&minv>f(sqrt_n)){pos=sqrt_n;minv=f(sqrt_n);}sqrt_n++;if(sqrt_n>=l&&sqrt_n<=r&&minv>f(sqrt_n)){pos=sqrt_n;minv=f(sqrt_n);}int L=l,R=pos;while(L<R){int mid=L+R>>1;if(f(mid)<=minv)R=mid;else L=mid+1;}cout<<R<<endl;
}

F. Tokitsukaze and Gold Coins (easy)

思路

tag:dfs,bfs,思维
求起点到终点最多可走多少格子,最简单的方法就是起点终点各跑一次bfs,然后找都可以做到的点。

const int N=5e5+10;
int n,k;
int g[N][4];
int st[N][4][2];
int dx[2][2],dy[2][2];
void bfs(PII start,bool f)
{queue<PII>q;q.push(start);if(f)st[start.x][start.y][f]=1;while(q.size()){auto t=q.front();q.pop();for(int i=0;i<2;i++){int a=t.x+dx[i][f],b=t.y+dy[i][f];if(a<=0||a>n||b<=0||b>3)continue;if(g[a][b]==1)continue;if(st[a][b][f])continue;st[a][b][f]=1;q.push({a,b});}}
}
void solve()
{cin>>n>>k;dx[0][0]=0,dx[1][0]=1,dx[0][1]=0,dx[1][1]=-1;dy[0][0]=1,dy[1][0]=0,dy[0][1]=-1,dy[1][1]=0;rep(i,1,n)rep(j,1,3)g[i][j]=0;rep(i,1,n)rep(j,1,3)rep(k,0,1)st[i][j][k]=0;rep(i,1,k){int x,y;cin>>x>>y;g[x][y]^=1;}bfs({1,1},0);bfs({n,3},1);int res=0;rep(i,1,n)rep(j,1,3)if(st[i][j][0]==st[i][j][1]&&st[i][j][0])res++;cout<<res<<endl;
}

G. Tokitsukaze and Gold Coins (hard)

待补。。。

H. Tokitsukaze and K-Sequence

思路

tag:哈希,差分,枚举,思维
我们发现,当前分成k组时,如果某种元素个数<=k,那么权值加上这一部分元素的个数,如果某种元素个数>k,则该种元素的造成的影响是k-1,累加即可。

int n;
const int N=1e5+10;
int a[N];
void solve()
{cin>>n;map<int,int>mp,mb;rep(i,1,n)cin>>a[i],mp[a[i]]++;for(auto x:mp)mb[x.y]++;vector<int>res(n+1,0);int s=mp.size();int cnt=0;rep(i,1,n){s-=mb[i];res[i]+=(i-1)*s;cnt+=mb[i]*i;res[i]+=cnt;}rep(i,1,n)cout<<res[i]<<endl;
}

I. Tokitsukaze and Musynx

思路

tag: 贪心,哈希,容斥
贪心的想,总权值最大,可能存在一个点处于v的边界上,再看数据范围,因此我们可以枚举边界(即H),用map存一下分别对应的改变区间,最后,分别枚举不同的H求maxv即可。此题难点在于贪心的考虑H在v边界上最优。

int n,m;
const int N=2e5+10;
int x[N],a[5];
int v[10];
map<int,vector<int>>mp;
void solve()
{mp.clear();cin>>n;rep(i,1,n)cin>>x[i],x[i]-=1e8;rep(i,1,4)cin>>a[i];rep(i,1,5)cin>>v[i];rep(i,1,n){rep(j,1,4){mp[a[j]-x[i]+(j==4)].pb(-j);mp[a[j]-x[i]+(j==4)].pb(j+1);}}int res=v[1]*n;int maxv=res;for(auto x:mp){for(auto y:x.y){if(y>0)res+=v[y];else res-=v[-y];}maxv=max(res,maxv);}cout<< maxv<<endl;
}

J. Tokitsukaze and Sum of MxAb

思路

tag:思维
枚举每个aia_iai发现,枚举到i时,res+=(n+1)∗abs(a[i])res+=(n+1)*abs(a[i])res+=(n+1)abs(a[i]),之后每个循环,都加一个abs(a[i])(n−1)次abs(a[i])(n-1)次abs(a[i])n1)次,所以对于每个a[i],res+=2∗n∗abs(a[i])a[i],res+=2*n*abs(a[i])a[i]res+=2nabs(a[i])

int n;
const int N=1e5+10;
int a[N];
void solve()
{cin>>n;int res=0;rep(i,1,n)cin>>a[i];rep(i,1,n)res+=2*n*abs(a[i]);cout<<res<<endl;
}

K. Tokitsukaze and Synthesis and Traits

思路

tag:图论
给出的图是无向不连通图,题目实际要求给k个点,判断图中有多少个出现过。
我们可以将图转换成有向无环图,转换方法是:度少的->度多的,度一样,编号小的->编号大的。
然后暴力搜索一下即可,时间复杂度m\sqrt mm

int n,m,q;
const int N=2e5+10;
int h[N],e[N<<1],ne[N<<1],idx;
int d[N];
int times[N];
vector<PII>edg;
void add(int a,int b)
{e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void solve()
{cin>>n>>m>>q;memset(h,-1,sizeof h);rep(i,1,m){int a,b;cin>>a>>b;d[a]++,d[b]++;edg.pb({a,b});	}rep(i,0,m-1){int a=edg[i].x,b=edg[i].y;if(d[a]<d[b])add(a,b);else{if(d[a]>d[b])add(b,a);else{if(a<b)add(a,b);else add(b,a);}}}vector<int>vec;while(q--){int k;cin>>k;vec.clear();rep(i,1,k){int x;cin>>x;vec.pb(x);times[x]=1;}int res=0;rep(u,0,k-1){for(int i=h[vec[u]];~i;i=ne[i]){int j=e[i];if(times[j])res++;}}cout<<res<<endl;for(auto x:vec)times[x]=0;}
}

L. Tokitsukaze and Three Integers

思路

tag: 容斥,哈希,预处理
这题思路不难,难在预处理上去重,定义f[i][j]:a或b选取v[i]时a*b(j)的个数。

int n,p;
const int N=5e3+10;
int a[N];
int f[N][N];
int cnt[N];
void solve()
{cin>>n>>p;rep(i,1,n)cin>>a[i];rep(i,1,n){rep(j,1,n){if(i==j)continue;cnt[a[i]%p*a[j]%p]++;f[i][a[i]%p*a[j]%p]+=2;}}rep(i,0,p-1){int res=0;rep(j,1,n){int t=a[j]%p;int v=(i-t+p)%p;res+=cnt[v]-f[j][v];}cout<<res<<' ';}
}

http://www.ppmy.cn/news/19017.html

相关文章

为什么会有右值引用?(移动构造、移动赋值)

目录 1、左值引用的缺陷 2、移动构造&#xff1a;解决临时对象的深拷贝 3、拓展&#xff1a;移动赋值 1、左值引用的缺陷 左值引用作为函数参数传递&#xff0c;减少了参数拷贝&#xff1b;但是作为函数返回值&#xff0c;并不适用于所有场景&#xff0c;比如要返回一个临…

使用 Grafana 请求API接口

目的: 使用Grafana 配合JSON API 插件 请求API接口,完成可视化,实现一些简单的请求功能 假设我们想将如下的API接口返回的json数据可视化 这里借用一下 小熊同学的 金融数据接口 用请求如下接口举例 https://api.doctorxiong.club/v1/fund/detail?code000001&startDat…

树莓派配置Python虚拟环境、安装PyQt5、安装PySide2

要从头设置好一台可用于开发的树莓派&#xff0c;可以参考树莓派 4B 无屏幕&#xff0c;连接WiFi、SSH、VNC&#xff0c;系统换源、pip换源&#xff0c;安装中文输入法 Python虚拟环境 树莓派&#xff08;或者说arm平台&#xff09;使用Python虚拟环境的正确方式是使用pipenv…

网关超详解

文章目录网关详解一、Spring Cloud Gateway用法二、实现三、网关的分类四、什么是网关五、网关的作用路由负载均衡统一鉴权统一处理跨域统一业务处理访问控制发布控制流量染色接口保护统一日志统一文档网关详解 一、Spring Cloud Gateway用法 去看官网&#xff1a;https://sp…

casbin权限和配置文件的理解

官方文档 基础权限模型 下图为我基于个人理解画出来的(关于多租户RBAC模型可能有误) 发现一篇博客讲的还行Casbin权限模型&#xff0c;看他的权限系统设计模型分析部分 casbin配置文件内容的结构解释 注意matchers可以设置多个。我在知道这个之前一直疑惑为什么需要policy_…

Sprig框架集成(SSM框架) | Sping+SpringMVC+Mybatis

SSM框架 SSM是spingspringMVCmybatis集成的框架&#xff1a;标准的MVC模式&#xff0c;整个系统划分为表现层&#xff0c;controller层&#xff0c;service层&#xff0c;DAO层四层 Spring&#xff08;业务层&#xff09; Spring就像是整个项目中装配bean的大工厂&#xff0c;在…

我的硕士前半生

本篇文章属于随笔类&#xff0c;它可能无法对你起到直接帮助&#xff0c;它只是我这个普通学生一年半以来的一些足迹与思考。本文首发于我的个人博客 Forever Young 我的本科像硕士&#xff0c;有实验室有工位&#xff0c;桌子超级大&#xff0c;有老师带有学长可以问。 我的硕…

mysql之存储过程

目录 1.概念 2.创建语法 3.调用 4.示例 5.删除 6.查看 1.概念 存储过程和函数类似java中的方法&#xff0c;能够提高代码的重用性&#xff0c;能够简化操作 一组预先编译好的SQL语句的集合&#xff0c;理解成批处理语句&#xff0c;减少了编译次数并且减少了和数据库服…