NOIP模拟17.8.20

A.阶乘
【题目描述】
亲爱的xyx同学正在研究数学与阶乘的关系,但是他喜欢颓废,于是他就制作了一个和阶乘有关系的数学游戏:
给出两个整数 n,m,令 t = !n,每轮游戏的流程如下
1.如果 m不能整除t ,即 t mod m ≠ 0,跳到第三步;如果能整除,跳到第二步
2.令 t = t/m,xyx的得分+1并返回第一步
3.游戏结束
xyx共进行T轮游戏,他想知道每轮他的得分是多少
【输入描述】
第一行一个整数 T,表示游戏轮数
接下来 T行,每行两个正整数n,m ,含义见题目描述
【输出描述】
共T 行,每行输出一个整数,表示xyx该轮游戏得到的分数
【样例输入】

4
2 3
3 3
23456 5
8735373 10
【样例输出】
0
1
5861
2183837
【限制与约定】
对于30% 的数据, n,m ≤ 20
对于60% 的数据, n,m ≤ 1e6
对于 100%的数据, n,m ≤ 1e9 ,T ≤ 10,1 < m <= 15

【题解】

此题极好

n! = 1*2*3*4*5*...*n

把m分解,设第i个质因数为pi,假设n中有k个pi

n! = 1*2*3..*pi*...*2pi*...*3pi*...*kpi...*n

然后我们让n/=pi,可以得到

n/pi! = 1*2*3*...*pi*...*2pi*...*3pi*...*(k - n/p - 1)pi*...*n/pi

证明比较显然,k*p每次-p就到达下一个p的倍数,于是,n每次-p,(n-p)!就

少一个p。干脆直接n不断/p就好了

最终结果要除以m中pi的数量

取一个min即可

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define min(a, b) ((a) < (b) ? (a) : (b)) inline void read(long long &x)
{
x = ;char ch = getchar(), c = ch;
while(ch < '' || ch > '')c = ch, ch = getchar();
while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();
if(c == '-')x = -x;
} const long long INF = 0x3f3f3f3f; long long n,m,t,ans; int main()
{
read(t);
register long long k,tmp,p;
for(;t;--t)
{
read(n), read(m);
ans = INF;
for(register int i = ;i <= m;++ i)
{
if(m % i == )
{
k = , p = n, tmp = ;
while(m % i == )m /= i, ++ k;
while(p)tmp += p/i, p/= i;
ans = min(ans, tmp/k);
}
}
printf("%I64d\n", ans);
}
return ;
}

T1

B.妹子
【题目描述】
亲爱的xyx同学正在研究数学与妹子的关系,但是他喜欢颓废,于是他就制作了一个和妹子有关系的数学游戏:
有一棵树,树上每个点i 有一个权值ai ,每轮游戏中xyx和妹子会各自选择一个点,然后对于树上所有的点来说,如果它与
xyx所选点的距离更近,那么xyx就会得到等于该点权值的分数;如果它与妹子所选点的距离更近,那么妹子就会得到等
于该点权值的分数;如果距离相等,那么xyx和妹子都不会得到分数。
xyx想知道,每轮游戏中,他和妹子得到的分数分别是多少
两点间的距离定义为该两点最短路径所经过的边的权值之和
【输入描述】
第一行一个整数 n,表示树的顶点数。
接下来n -1行,每行两个整数 u,v,w,表示第i 条边连接点 u,v,边权为w
接下来一行共 n个整数,表示树上每个点 i的权值ai 。
接下来一行一个整数 m,表示游戏轮数
接下来 m行,每行两个整数x,y ,分别表示xyx所选的点和妹子所选的点
【输出描述】
共 m行,每行输出两个整数,表示xyx得到的分数和妹子得到的分数,中间用一个空格隔开。
【样例输入】
3
1 2 1
1 3 1
10 1 1
2
2 3
1 3
【样例输出】
1 1
11 1
【限制与约定】
对于10% 的数据, n,m ≤ 100
对于30%的数据, n,m ≤ 1000
对于另外15% 的数据,第 i条边连接点i,i+1
对于另外15% 的数据,树和询问保证随机生成
对于 100%的数据,n ≤ 100000,m ≤ 50000,1 ≤ x, y,u, v ≤ n,1 ≤ w,ai ≤ 10

【题解】

此题极好+1

考察细节,参见代码

“点的类型可以看成是单调的(属于x->谁都不属于->属于y)
设dis[x]表示x到根的距离,每次询问中dis[x]>dis[y],他们的lca为p
那么点的类型边界一定在p->x的路径上

由于在链上存在单调性,可以二分+倍增找深度差为k的父亲来做
复杂度O(n log^2 n)
也可以倍增+从高到低确定二进制位,这一位是1时如果已经不受x控制,则这一位一定为0;反之这一位为0(贪心思路)
复杂度O(n log n)”
——张浩南

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring> inline void read(long long &x)
{
x = ;char ch = getchar(),c = ch;
while(ch < '' || ch > '')c = ch, ch = getchar();
while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();
if(c == '-')x = -x;
} const long long MAXN = + ; struct Edge
{
long long u,v,next,w;
Edge(long long _u, long long _v, long long _next, long long _w){u = _u;v = _v;next = _next;w = _w;}
Edge(){}
}edge[MAXN << ]; long long n,m,b[MAXN],value[MAXN],sum[MAXN],path[MAXN],p[][MAXN],deep[MAXN],fa[MAXN],head[MAXN],cnt; inline void insert(long long a, long long b, long long c)
{
edge[++cnt] = Edge(a,b,head[a],c);
head[a] = cnt;
} void dfs(long long u)
{
b[u] = ;
sum[u] = value[u];
for(register long long pos = head[u];pos;pos = edge[pos].next)
{
long long v = edge[pos].v;
if(b[v])continue;
path[v] = path[u] + edge[pos].w;
deep[v] = deep[u] + ;
dfs(v);
fa[v] = u;
p[][v] = u;
sum[u] += sum[v];
}
} //p[0]是点 p[1]是路径长度
inline void yuchuli()
{
long long M = ;
while(( << M) <= n)++ M;
-- M;
for(register long long i = ;i <= M;++ i)
for(register long long j = ;j <= n;++ j)
p[i][j] = p[i - ][p[i - ][j]];
} long long lca(long long va, long long &vb)
{
int flag = ;
if(deep[va] < deep[vb])
{
long long tmp = va;
va = vb;
vb = tmp;
flag = ;
}
long long M = ;
while(( << M) + deep[vb] <= deep[va])++ M;
-- M;
for(register long long i = M;i >= ;-- i)
if(( << i) + deep[vb] <= deep[va])
va = p[i][va];
if(va == vb)return va;
M = ;
while(( << M) + deep[vb] <= n)++ M;
-- M;
for(register long long i = M;i >= ;-- i)
if(p[i][va] != p[i][vb])
{
va = p[i][va];
vb = p[i][vb];
}
if(flag)vb = va;
return p[][va];
} int main()
{
read(n);
register long long tmp1, tmp2, tmp3;
for(register long long i = ;i < n;++ i)
{
read(tmp1),read(tmp2),read(tmp3);
insert(tmp1, tmp2, tmp3);
insert(tmp2, tmp1, tmp3);
}
for(register long long i = ;i <= n;++ i) read(value[i]);
deep[] = ;
dfs();
yuchuli();
read(m);
register long long a,b,ans1,ans2,lenth,sa,sb,c,ok,M = ;
while(( << M) <= n)++ M;
-- M;
for(register long long i = ;i <= m;++ i)
{
read(a),read(b);
if(a == b)
{
printf("0 0\n");
continue;
}
ok = ;
if(path[a] < path[b])
{
int tmp = a;
a = b;
b = tmp;
ok = ;
}
sa = a, sb = b;
c = lca(sa, sb);
ans1 = ans2 = ;
/* if(c != 0)*/
lenth = path[a] + path[b] - (path[c] << );
/* else
lenth = path[a] - path[b];*/
for(register int i = M;i >= ;-- i)
if(((path[a] - path[p[i][sa]]) * ) < lenth)
sa = p[i][sa];
if(((path[a] - path[p[][sa]]) << ) == lenth)
{
if(p[][sa] == c)
{
if(ok)
printf("%lld %lld\n", sum[sb], sum[sa]);
else
printf("%lld %lld\n", sum[sa], sum[sb]);
continue;
}
else
{
if(ok)
printf("%lld %lld\n", sum[] - sum[fa[sa]], sum[sa]);
else
printf("%lld %lld\n", sum[sa], sum[] - sum[fa[sa]]);
continue;
}
}
else
{
if(ok)
printf("%lld %lld\n", sum[] - sum[sa], sum[sa]);
else
printf("%lld %lld\n", sum[sa], sum[] - sum[sa]);
continue;
}
}
return ;
}

T2

这题我调了很久,最后发现我本以为最不可能错的LCA居然写挂了,其他地方都没错。。。

C.在
【题目描述】
亲爱的xyx同学正在研究数学与存在的关系,但是他喜欢颓废,于是他就制作了一个和存在有关系的数学游戏:
有一个集合,游戏开始时里面有一些数,xyx每次可以选择集合中的两个数(这两个数可以是同一个数)相减,然后把它
们差的绝对值放入集合中(如果集合中已存在该数则不放入),经过任意次这样的操作后,xyx会给出一个数字 k,问它
是否能存在在集合中,如果能,那么游戏成功,反之失败。
(换句话说,xyx想知道这样不断操作下去,是否能凑出数字 k)
xyx有一个数列 a,他每次会给出三个数 l,r,x,即把所有的ai(l ≤ i ≤ r) 放入集合中,并且想要知道当 k = x时游戏是否成功
有多组询问且询问之间相互独立,你可以认为每次询问后xyx就把游戏中的集合清空了
【输入描述】
第一行两个整数n 和 m,分别表示数字集合的大小和询问次数。
第二行共 n个整数,表示数列 a,第 i个数是 ai。
接下来 m行,每行三个整数 l,r,x,含义见题目描述
【输出描述】
共 m行,每行一个字符串,表示对应询问的答案,如果游戏成功输出”win”,反之输出”lose”。(不输出引号)
【样例输入】
7 5
3 6 4 2 7 1 8
1 2 3
3 7 0
3 4 2
3 4 5
2 3 3
【样例输出】
win
win
win
lose
lose
【限制与约定】
对于20% 的数据, ai,x ∈ [0,1]
对于另外20% 的数据,保证 ai 随机生成
对于另外 20%的数据, l = 1
对于100% 的数据, n,m ≤ 100000,0 ≤ x,ai ≤ 10 ,1 ≤ l ≤ r ≤ n

【题解】

此题一般

当时场外试了几组数据,然后就看出来了

其实能不能凑出k,取决于两个条件:

1、数列中存在大于等于k的数

2、数列的gcd为k的因数

很显然,数列每个数都可以写作p*gcd的性质,他们加减,仍是p*gcd

每次写st表都要手推。。。所以注释里保存了我手推的过程,便于大家学习。。。

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define max(a, b) ((a) > (b) ? (a) : (b)) inline void read(int &x)
{
x = ;char ch = getchar(),c = ch;
while(ch < '' || ch > '')c = ch, ch = getchar();
while(ch <= '' && ch >= '')x = x * + ch - '', ch = getchar();
if(c == '-')x = -x;
} const int MAXN = + ; /*
data[i][j]表示区间[j, j + 2^i - 1]
data[i][j] = gcd(data[i - 1][j], data[i - 1][j + 2^(i - 1)]
[j, j + 2^(i - 1) - 1] [j + 2 ^ (i - 1), j + 2^ i - 1] [l,r]
2 ^ M <= r - l + 1 < 2 ^ (M + 1)
data[M][l], data[M][r - 2^M + 1]
*/
int n,m,num[MAXN],data[][][MAXN],lo[MAXN],pow2[]; inline int gcd(int a, int b)
{
return b == ? a : gcd(b, a % b);
} inline void yuchuli()
{
int M = lo[n];
for(register int i = ;i <= M;++ i)
for(register int j = ;j <= n;++ j)
{
data[][i][j] = gcd(data[][i - ][j], data[][i - ][j + pow2[i - ]]);
data[][i][j] = max(data[][i - ][j], data[][i - ][j + pow2[i - ]]);
}
} int findma(int l, int r)
{
return max(data[][lo[r - l + ]][l], data[][lo[r - l + ]][r - pow2[lo[r - l + ]] + ]);
} int findgcd(int l, int r)
{
return gcd(data[][lo[r - l + ]][l], data[][lo[r - l + ]][r - pow2[lo[r - l + ]] + ]);
} int main()
{
read(n);read(m);
lo[] = ;
for(register int i = ;i <= n;++ i)lo[i] = lo[i >> ] + ;
pow2[] = ;
for(register int i = ;i <= ;++ i)pow2[i] = pow2[i - ] << ;
for(register int i = ;i <= n;++ i)read(num[i]), data[][][i] = data[][][i] = num[i];
yuchuli();
register int l,r,k;
for(register int i = ;i <= m;++ i)
{
read(l),read(r),read(k);
int ma = findma(l, r);
if(ma < k)
{
printf("lose\n");
continue;
}
int g = findgcd(l, r);
if(g == ) printf("win\n");
else if(k % g == )
{
printf("win\n");
continue;
}
else
{
printf("lose\n");
continue;
}
}
return ;
}

T3

NOIP模拟 17.8.20的更多相关文章

  1. NOIP模拟17.9.21

    NOIP模拟17.9.21 3 58 145 201 161.5 样例输出21.6 数据规模及约定对于40% 的数据,N <= 20对于60% 的数据,N <= 1000对于100% 的数 ...

  2. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  3. NOIP模拟 17.8.18

    NOIP模拟17.8.18 A.小菜一碟的背包[题目描述]Blice和阿强巴是好朋友但萌萌哒Blice不擅长数学,所以阿强巴给了她一些奶牛做练习阿强巴有 n头奶牛,每头奶牛每天可以产一定量的奶,同时也 ...

  4. NOIP模拟 17.8.15

    NOIP模拟17.8.15 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  5. NOIP模拟 17.8.16

    NOIP模拟17.8.16 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  6. NOIP模拟 17.8.14

    NOIP模拟17.8.14 (天宇哥哥考察细心程度的题) [样例解释]如果删去第一个 1:在[3,1,2]中有 3 个不同的数如果删去 3:在[1,1,2]中有 2 个不同的数如果删去第二个 1:在[ ...

  7. NOIP模拟 17.8.17

    NOIP模拟17.8.17 A 小 G 的字符串文件名 输入文件 输出文件 时间限制 空间限制str.pas/c/cpp str.in str.out 1s 128MB[题目描述]有一天,小 L 给小 ...

  8. NOIP模拟 17.9.28

    公交车[问题描述]市内有

  9. Noip模拟17 2021.7.16

    我愿称这场考试为STL专练 T1 世界线 巧妙使用$bitset$当作vis数组使用,内存不会炸,操作还方便,的确是极好的. 但是这个题如果不开一半的$bitset$是会炸内存的,因为他能开得很大,但 ...

随机推荐

  1. zip压缩工具类

    java将有关zip压缩的内容都封装在java.util.zip宝中,用java实现zip压缩,不用考虑压缩算法,java已经将这些进行了封装 实际上用java实现zip压缩涉及的就是一个“输入输出流 ...

  2. ALS算法实现用户音乐打分预测

    很多人在决定是否看一部电影之前都会去豆瓣看下评分作为参考,看完电影也会给一个自己的分数.每个人对每个商品或者电影或是音乐都有一个心理的分数,这个分数标明用户是否对这个内容满意.作为内容的提供方,如果可 ...

  3. Django项目:CRM(客户关系管理系统)--82--72PerfectCRM实现CRM动态菜单和角色

    #models.py # ————————01PerfectCRM基本配置ADMIN———————— from django.db import models # Create your models ...

  4. win 7下安装mysql zip格式

    mysql 下载地址:https://dev.mysql.com/downloads/mysql/5.5.html#downloads 下载的mysql格式为zip: 下载完成放在除C盘以外的盘. 一 ...

  5. Python-新手爬取安居客新房房源

    新手,整个程序还有很多瑕疵. 1.房源访问的网址为城市的拼音+后面统一的地址.需要用到xpinyin库 2.用了2种解析网页数据的库bs4和xpath(先学习的bs4,学了xpath后部分代码改成xp ...

  6. 解读Python中 locals() 和 globals() 内置函数

    首先globals() 和 locals() 是作用于作用域下的内置函数,所以我将它们分为作用域类型的内置函数 1.作用域相关: 1)globals() # 返回全局作用域中的所有名字 2)local ...

  7. Hibernate-一对多|多对一-多对多

    1 一对多|多对一 1.1 关系表达 表中的表达 表中的表达  实体中的表达 orm元数据中表达 一对多 多对一 1.2 操作 操作关联属性 1.3 进阶操作 级联操作 结论: 简化操作.一定要用,s ...

  8. LA3695 Distant Galaxy

    Distant Galaxy https://vjudge.net/problem/UVALive-3695 You are observing a distant galaxy using a te ...

  9. ETH功能类

    <?php /** * Ethereum JSON-RPC interface * * See Ethereum API documentation for more information: ...

  10. 03Redis入门指南笔记(事务、生存时间、排序、消息通知、管道)

    一:事务 1:概述 Redis中的事务(transaction)是一组命令的集合.事务同命令一样都是Redis的最小执行单位,一个事务中的命令要么都执行,要么都不执行. 事务的原理是是先将属于一个事务 ...