考点难度都很合适的一套题目,大概在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. 网络流 之 dinic 算法

    网络流指的是:网络流(network-flows)是一种类比水流的解决问题方法.(类似于水管群,有一个源点(水无限多),和一个汇点,最大流就代表这个点水管群(边集)每秒最大能送道汇点的水量) 这个怎么 ...

  2. Nginx+Tomcat+Memcache 实现session共享

    Nginx + Tomcat + Memcache 实现session共享 1. Nginx 部署 1.上传源码包到服务器,解压安装 下载地址:http://nginx.org/en/download ...

  3. 连接树莓派中的MySQL服务器

    今天用笔记本连接树莓派的 MySQL ,结果连接不上.就直接连接到树莓派上进行操作.其实以前也知道远程访问 MySQL 需要进行配置,可以直接 mysql.user 表,也可以直接使用授权的 SQL ...

  4. 【linux】glibc升级

    glibc升级 步骤如下: 1.下载解压glibc wget http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz tar zxvf glibc-2.18.ta ...

  5. 【题解】ADAGRAFT - Ada and Graft [SP33331]

    [题解]ADAGRAFT - Ada and Graft [SP33331] 传送门:\(\text{Ada and Graft}\) \(\text{[SP33331]}\) [题目描述] 给出一颗 ...

  6. java架构之路(mysql底层原理)Mysql之Explain使用详解

    上篇博客,我们详细的说明了mysql的索引存储结构,也就是我们的B+tree的变种,是一个带有双向链表的B+tree.那么我今天来详细研究一下,怎么使用索引和怎么查看索引的使用情况. 我们先来简单的建 ...

  7. 高性能TcpServer(C#) - 3.命令通道(处理:掉包,粘包,垃圾包)

    高性能TcpServer(C#) - 1.网络通信协议 高性能TcpServer(C#) - 2.创建高性能Socket服务器SocketAsyncEventArgs的实现(IOCP) 高性能TcpS ...

  8. 使用EF批量新增数据十分缓慢

    使用EF来批量新增数据,发现效率非常的差,几千条数据时甚至需要几分钟来执行,迫于无奈使用sql来执行了. 今天偶然看到一篇关于EF的文章,才发觉原来是自己对EF不够了解的原因. 一般新增时我们是将所有 ...

  9. .NET Core 收徒,有缘者,可破瓶颈

    最近感悟天命,偶有所得,故而打算收徒若干,以继吾之传承. 有缘者,可破瓶颈,职场巅峰指日可待. 入门基本要求: 1.工作经验:1年或以上. 2.拜师费用:3999元(RMB). 传承说明: 1.收徒人 ...

  10. python类模拟电路实现

    实现电路: 实现方法: class LogicGate(object): def __init__(self, n): self.name = n self.output = None def get ...