考点难度都很合适的一套题目,大概在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. mysql-新增数据表

    新增数据表之前,需确保已经存在数据库,如还没有数据库请先参考上一篇文章新增数据库 1.创建表  create table test( id  int PRIMARY KEY, name  varcha ...

  2. div+css画一个小猪佩奇

    用DIV+CSS画一个小猪佩奇,挺可爱的,嘻嘻. HTML部分(全是DIV) <!-- 小猪佩奇整体容器 --> <div class="pig_container&quo ...

  3. golang两种在for循环中使用goroutine的错误形式

    1. 闭包中使用循环体中变化的量 platground链接: https://play.golang.org/p/6x6_tuQNjUO type Value struct{ val int } fu ...

  4. 深入理解TCP/IP应用层

    TCP/IP四层模型分为: 应用层,传输层(只关注起点(发送者)和终点(接收者)),网络层(规划出一条或几条路线),数据链路层(关注两个相邻点之间怎么传输)   协议   应用层 DNS,URI,HT ...

  5. AppScan基础使用 - 初学篇

    最近找工作,阿里的面试官问过了安全,以前面试中也问到了安全,呆过的公司,朋友呆过的公司,发现安全测试很少 ,可能是应用的比较少. 当今社会安全还是比较重要的,学学有好处,大概了解下  .因为个人比较懒 ...

  6. 妹纸对网易严选的Bra是什么评价?

    声明:这是一篇超级严肃的技术文章,请本着学习交流的态度阅读,谢谢! 一.网易商品评论爬取 1.评论分析 进入到网易严选官网,搜索“文胸”后,先随便点进一个商品. 在商品页面,打开 Chrome 的控制 ...

  7. DesignPattern系列__07合成复用原则

    基本介绍 合成复用原则的核心,就是尽量去使用组合.聚合等方式,而不是使用继承. 核心思想 1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起. 2.针对接口编程,而不是 ...

  8. windows zlib库编译步骤

    下载地址 http://www.zlib.net/ 动态库下载地址 如果自己实在不想编译的,可以直接下载 https://download.csdn.net/download/zhangxuechao ...

  9. Android中获取实时网速(2)

    一.实现思路: 1.Android提供有获取当前总流量的方法 2.上一秒 减去 下一面的流量差便是网速 3.注意计算 二.计算网速的工具类: package imcs.cb.com.viewappli ...

  10. Spring Cloud Eureka的自我保护模式与实例下线剔除

    之前我说明了Eureka注册中心的保护模式,由于在该模式下不能剔除失效节点,故按原有配置在实际中不剔除总感觉不是太好,所以深入研究了一下.当然,这里重申一下,不管实例是否有效剔除,消费端实现Ribbo ...