考点难度都很合适的一套题目,大概在day1到day2之前

T1

猴猴最喜欢在树上玩耍,一天猴猴又跳上了一棵树,这棵树有N个苹果,每个苹果有一个编号,分
别为0~N-1,它们之间由N-1个树枝相连,猴猴可以从树枝的一端爬到树枝的另一端,所以猴猴可
以从任意一个苹果的位置出发爬到任意猴猴想去的苹果的位置。猴猴开始在编号为K的苹果的位
置,并且把这个苹果吃了,之后每一天猴猴都要去吃一个苹果,但是树上那么多苹果吃哪个呢?
猴猴想到自己去吃苹果时一定会把路上遇到的苹果都吃掉,于是猴猴决定去吃能让自己这天吃的
苹果数量最多的那个苹果,如果有多个苹果满足条件,猴猴就会去吃这些中编号最小的苹果,那
么猴猴会按照什么顺序吃苹果呢?

对于30%的数据:N<=100
对于60%的数据:N<=1000
对于100%的数据:N<=50000,0<=K<N

分析:60%的分数都只要暴力模拟就好了,每次找最长的走过去;

考虑一个性质:走过的点的权值会消失,那么每次移动到终点位置和每次都从初始给定的点出发的答案都一样的,而且终点一定会是叶子节点;

那么我们设初始节点为根节点,先进行一遍dfs,把所有叶子节点记录下来,按照深度排序;

然后让每个点沿着父亲往上跳,每跳一步答案增加1,遇到根节点或者走过的节点就停止(遇到走过的点说明上面的权值都没有了

然后把叶子节点按答案从小到大输出(看完题解觉得智商被人按在地上摩擦了)

#include<bits/stdc++.h>
using namespace std;
namespace knife_rose{
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mid ((l+r)>>1)
inline int read()
{
int x=;char ch,f=;
for(ch=getchar();(ch<''||ch>'')&&ch!='-';ch=getchar());
if(ch=='-') f=,ch=getchar();
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
}
const int N=1e5+;
int n,rt;
int head[N],cnt;
struct point
{
int nxt,to;
point(){}
point(const int &nxt,const int &to):nxt(nxt),to(to){}
}a[N<<];
inline void link(int x,int y)
{
a[++cnt]=(point){head[x],y};head[x]=cnt;
a[++cnt]=(point){head[y],x};head[y]=cnt;
}
int f[N],dep[N],lea[N],num,sum[N];
bool vis[N];
inline void dfs(int now,int fa)
{
f[now]=fa;
dep[now]=dep[fa]+;
bool flag=;
for(int i=head[now];i;i=a[i].nxt)
{
int t=a[i].to;
if(t==fa) continue;
flag=;
dfs(t,now);
}
if(!flag) lea[++num]=now;
}
inline bool cmp1(int a,int b)//深度排序,深度相同按编号大小
{
return dep[a]^dep[b]?dep[a]>dep[b]:a<b;
}
inline bool cmp2(int a,int b)//答案排序
{
return sum[a]^sum[b]?sum[a]>sum[b]:a<b;
}
signed main()
{
n=read(),rt=read();
for(int x,i=;i<n;++i)
{
x=read();
link(x,i);
}
dfs(rt,rt);
sort(lea+,lea+num+,cmp1);
vis[rt]=;
for(int i=;i<=num;++i)
{
int now=lea[i];
while(!vis[now])
{
++sum[lea[i]];
vis[now]=;
now=f[now];
}
}
sort(lea+,lea+num+,cmp2);
printf("%d\n",rt);
for(int i=;i<=num;++i) printf("%d\n",lea[i]);
return ;
}
}
signed main()
{
return knife_rose::main();
}

T2

猴猴最爱吃香蕉了。每天猴猴出门都会摘很多很多的香蕉,每个香蕉都有一个甜度,猴猴不一定
要把所有的香蕉都吃掉,猴猴每天都有一个心情值K,猴猴希望当天吃的香蕉满足这么一个条件,
这些香蕉的甜度乘积恰好等于K,但是猴猴并不知道有多少种方法,于是猴猴把这个问题交给你。

对于30%的数据:n,K<=100
对于60%的数据:n<=1000,K<=10000
对于100%的数据:n<=1000,K<=100000000,D<=20(D是数据组数

30%:我也没想出来咋拿30分(

60%:题目是个很明显的背包,但是由于是乘法所以有一些特殊之处:只有k的约数才能作为转移,所以我们可以筛出来k的约数,是根号量级的;

统计答案需要二分查找,复杂度O(D×n√k×log(√k))

100%:其实上面那个做法就是100分,然而官方题解也是这么给的,但是很明显复杂度不对啊qwq

然而机房里某位巨佬想出了复杂度更优秀的做法,%%%szx

先对k进行质因数分解,根据每个质因子个数将答案压缩成一个多进制状态,然后将每个a[i]也压缩成对应的多进制状态进行转移,可以发现质因子个数很少,不超过30个

设t是多进制状态最大值

复杂度为O(√k+n√a[i]+nt)

#include<bits/stdc++.h>
using namespace std;
namespace knife_rose{
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mid ((l+r)>>1)
inline int read()
{
int x=;char ch,f=;
for(ch=getchar();(ch<''||ch>'')&&ch!='-';ch=getchar());
if(ch=='-') f=,ch=getchar();
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
}
const int N=1e4+,p=1e9+;
int tyx,n,m,ed,tot;
int a[N];
int st[],sum[],top;
int git[],c[],s[N][];
int g[N],f[];
bool vis[N];
inline void clear()
{
memset(g,,sizeof(g));
memset(f,,sizeof(f));
memset(sum,,sizeof(sum));
memset(s,,sizeof(s));
memset(vis,,sizeof(vis));
top=;
}
signed main()
{
tyx=read();
while(tyx--)
{
clear();
n=read(),m=read();
for(int i=;i<=n;++i) a[i]=read();
int qr=sqrt(m),tmp=m;
for(int i=;i<=qr;++i)
{
if(tmp%i==)
{
st[++top]=i;
while(tmp%i==) ++sum[top],tmp/=i;//质因数分解
}
}
if(tmp^) st[++top]=tmp,sum[top]=;//加上大质因子
git[]=;
for(int i=;i<=top;++i)
git[i+]=git[i]*(sum[i]+);//git[i]表示,多进制状态下,第i位一个1代表十进制多少
ed=;
for(int i=;i<=top;++i) ed+=git[i]*sum[i];//ed是最终状态
for(int i=;i<=n;++i)
{
if(m%a[i]){vis[i]=;continue;}//不是M的约数没用
qr=sqrt(a[i]),tot=;
for(int j=;j<=qr;++j)
{
if(a[i]%j==)
{
c[++tot]=j;
while(a[i]%j==) ++s[i][tot],a[i]/=j;//质因数分解*2
}
}
if(a[i]^) c[++tot]=a[i],s[i][tot]=;
int t=;
for(int j=;j<=top;++j)
{
while(c[t]<st[j]&&t<tot) ++t;
if(c[t]==st[j]) g[i]+=git[j]*s[i][t];//g[i]为a[i]对应的多进制状态数
}
}
f[]=;
for(int t,now,flag,i=;i<=n;++i)
{
if(vis[i]) continue;
for(int j=ed;~j;--j)
{
flag=;
t=;
for(int k=;k<=top;++k)
{
now=(j%git[k+])/git[k];//now是a[i]对应的g[i]在第i位有多大
if(now+(g[i]%git[k+])/git[k]>sum[k]){flag=;break;}//如果第i位当前数字+g[i]的第i位数字大于上界取消
t+=(now+(g[i]%git[k+])/git[k])*git[k];
}
if(flag) continue;
f[t]+=f[j];
if(f[t]>=p) f[t]-=p;
}
}
printf("%d\n",f[ed]);
}
return ;
}
}
signed main()
{
return knife_rose::main();
}
/*
1
10 10
1 5 1 2 4 5 1 2 1 5 */

T3

猴猴今天要和小伙伴猩猩比赛爬树,为了公平不碰撞,猴猴和猩猩需要在不同的树上攀爬。于是
它们选了两颗节点数同为n的树,并将两棵树的节点分别以1~n标号(根节点标号为1),但两棵树
的节点连接方式不尽相同。
现在它们决定选择两个标号的点进行比赛。为了方便统计,规定它们比赛中必须都向上爬。(即
选定的赛段节点u→节点v都必须指向叶子方向)请你求出这两棵树上共有多少对节点满足比赛的需
求。

对于30%的数据:n≤1000
对于50%的数据:n≤10000
对于100%的数据:n≤100000,1≤a,b≤n

题意大概是选一对点使得在这两颗树上都满足某个点是另一个点的祖先

30%:记录每个点是不是在两棵树上都是自己祖先,枚举点对

50%:???好像没啥办法

100%:其实这个题目就是一个树上逆序对问题,我们考虑先对第一颗树以dfs序为下标建树状数组,再遍历第二棵树,每次进去的先把自己放进树状数组,然后求一下当前子树范围内点的个数,出来的时候再求一遍,两次结果作差就是满足题目要求的点对(进去的时候不存在而回溯的时候存在说明既是第一颗树的子树也是第二棵树的子树)

#include<bits/stdc++.h>
using namespace std;
namespace knife_rose{
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define mid ((l+r)>>1)
inline int read()
{
int x=;char ch,f=;
for(ch=getchar();(ch<''||ch>'')&&ch!='-';ch=getchar());
if(ch=='-') f=,ch=getchar();
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
}
const int N=1e5+;
int n,ret;
int head[N],cnt;
struct point
{
int nxt,to;
point(){}
point(const int &nxt,const int &to):nxt(nxt),to(to){}
}a[N<<];
inline void link(int x,int y)
{
a[++cnt]=(point){head[x],y};head[x]=cnt;
a[++cnt]=(point){head[y],x};head[y]=cnt;
}
int st[N],ed[N],idx;
inline void dfs1(int now,int fa)
{
st[now]=++idx;
for(int i=head[now];i;i=a[i].nxt)
{
int t=a[i].to;
if(t==fa) continue;
dfs1(t,now);
}
ed[now]=idx;
}
int tr[N];
inline int lowbit(int i)
{
return i&-i;
}
inline void update(int x,int k)
{
for(int i=x;i<=n;i+=lowbit(i))
tr[i]+=k;
}
inline int query(int y)
{
int ret=;
for(int i=y;i;i^=lowbit(i))
ret+=tr[i];
return ret;
}
inline void dfs2(int now,int fa)//树上逆序对
{
int ans=query(ed[now])-query(st[now]-);
for(int i=head[now];i;i=a[i].nxt)
{
int t=a[i].to;
if(t==fa) continue;
dfs2(t,now);
}
ret+=query(ed[now])-query(st[now]-)-ans;
update(st[now],);
}
signed main()
{
n=read();
for(int x,y,i=;i<n;++i)
{
x=read(),y=read();
link(x,y);
}
dfs1(,);
memset(head,,sizeof(head));
cnt=;
for(int x,y,i=;i<n;++i)
{
x=read(),y=read();
link(x,y);
}
dfs2(,);
printf("%d\n",ret);
return ;
}
}
signed main()
{
return knife_rose::main();
}

10.24考试题解qwq的更多相关文章

  1. 题解 2020.10.24 考试 T2 选数

    题目传送门 题目大意 见题面. 思路 本来以为zcx.pxj变强了,后来发现是SPJ出问题了...考试的时候感觉有点人均啊...结果自己还是只想出来一半. 我们假设 \(f(x)=(\lfloor\f ...

  2. 题解 2020.10.24 考试 T4 模板

    题目传送门 题目大意 有一个 \(n\) 个点组成的树,有 \(m\) 次操作,每次将 \(1\to x\) 的路径上每个点都加入一个颜色为 \(c\) 的小球.但是每个点都有大小限制,即小球个数超过 ...

  3. 题解 2020.10.24 考试 T3 数列

    题目传送门 题目大意 给出一个数 \(n\),你要构造一个数列,满足里面每个数都是 \(n\) 的因子,且每一个数与前面不互质的个数不超过 \(1\).问有多少种合法方案. 保证 \(n\) 的不同质 ...

  4. 10.24 正睿停课训练 Day8 AM

    目录 2018.10.24 正睿停课训练 Day8 AM A 棒棒糖(组合) B 彩虹糖(思路 博弈) C 泡泡糖(DP) 考试代码 A B C 2018.10.24 正睿停课训练 Day8 AM 期 ...

  5. 2016 10 28考试 dp 乱搞 树状数组

    2016 10 28 考试 时间 7:50 AM to 11:15 AM 下载链接: 试题 考试包 这次考试对自己的表现非常不满意!! T1看出来是dp题目,但是在考试过程中并没有推出转移方程,考虑了 ...

  6. 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令

    [源码下载] 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 作者:webabcd ...

  7. Leetcode 10. 正则表达式匹配 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  8. python中使用Opencv进行车牌号检测——2018.10.24

    初学Python.Opencv,想用它做个实例解决车牌号检测. 车牌号检测需要分为四个部分:1.车辆图像获取.2.车牌定位.3.车牌字符分割和4.车牌字符识别 在百度查到了车牌识别部分车牌定位和车牌字 ...

  9. table-cell http://www.cnblogs.com/StormSpirit/archive/2012/10/24/2736453.html

    http://www.cnblogs.com/StormSpirit/archive/2012/10/24/2736453.html

随机推荐

  1. PostgreSQL CentOS 7 安装配置

    https://www.postgresql.org/download/ 选择相应的版本 安装完成后,稍微配置下,否则无法远程访问: cd /var/lib/pgsql/11/data vi post ...

  2. Pencil 基于Electron的GUI原型工具之菜单再探

    为什么要重试呢? 主要是觉得Pencil这个工具还是比较有价值.就像Linus对Linux下分发版的态度"让用户有选择"一样,在现在这个Sass服务.Web服务化越来越普遍越便利的 ...

  3. resharper 8.2

    用户名:ronle注册码:ZoJzmeVBoAv9Sskw76emgksMMFiLn4NM

  4. Python连载36-线程数量限制、Timer、可重入锁

    一.允许一个资源最多由几个线程同时进行 命令行:threading.Semaphore(个数) 代表现在最多有几个线程可以进行操作 import threading import time #参数定义 ...

  5. Spring源码系列 — Envoriment组件

    何为Envoriment Envoriment是集成在Spring上下文容器中的核心组件,在Spring源码中由Envoriment接口抽象. 在Environment中,有两大主要概念: Profi ...

  6. SpringBoot多数据源动态切换数据源

    1.配置多数据源 spring: datasource: master: password: erp_test@abc url: jdbc:mysql://127.0.0.1:3306/M201911 ...

  7. SqlServer 开篇简介

    实例:我们的电脑中可以安装一个或多个SqlServer实例,每一个SqlServer实例可以包含一个或者多个数据库. 架构:数据库中,又有一个或者多个架构.架构里面包含:表,视图,存储过程. 文件与文 ...

  8. 用maven对ssm进行整合

    网上有很多ssm整合的教程,这里给像我这样的初学的新手提供一个整合方法,同时也记录一下自己的学习进度. 同时推荐观看相关视频  https://www.bilibili.com/video/av536 ...

  9. csp201809-2 买菜

    问题描述 小H和小W来到了一条街上,两人分开买菜,他们买菜的过程可以描述为,去店里买一些菜然后去旁边的一个广场把菜装上车,两人都要买n种菜,所以也都要装n次车.具体的,对于小H来说有n个不相交的时间段 ...

  10. html 实体编码转换成原字符

    今天遇到件很恶心的事,某国外歌词网站提供的歌词在源文件里使用“&#数字;”格式的编码表示abcd....原来小菜我实在才疏学浅不知此为何物,于是特有的搜索引擎控,搜之.片刻得解,此乃html实 ...