这场考试考得很烂

连暴力都没打好

只拿了25分,,,,,,,,好好总结

T1序列

A. 序列

题目描述

HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进。

郭神作为摄像师想要选取其中一段照下来。他想让这一段中每个人的身高成等比数列,展示出最萌身高差,但他发现这个太难办到了,于是他决定放低要求,让等比数列的每两项之间可以是不连续的(例如
2,4,16……)。可他依然找不到满意的,便再次妥协,使这个等比数列可以是乱序的。

现在请在其中你找出最长的符合要求的一段,使得将这一段排序后为某个公比为q的等比数列的子序列(q∈N*,q<=1000)。

输入格式

第一行一个正整数n,表示有n个人。

接下来n行每行一个正整数a1,a2..an,依次表示n个人的身高。

输出格式

一行一个整数ans,表示最长的符合要求的连续一段。

样例

样例输入

【样例输入1】
7
2
4
6
6
1
36
3
【样例输出1】
3

样例输出

【样例输入2】
10
1
2
3
4
5
6
7
8
9
10
【样例输出2】
2

数据范围与提示

对于20%的数据 n<=100

对于40%的数据 n<=1000

对于另外 20%的数据 ai<=100

对于100%的数据 n<=100000,ai<=10^18

这题应该是最简单的一个题了

思路倒是不难想,,考场上想出来了要nlogn做,思路大概对了一半,在处理的时候有一些问题

只得了5pts

重新看看这道题

题意:

  在一个序列中找到一个最长的子序列,使它排序后是一个不完整的等比数列(公比<=1000)

可以看到公比小的不的了,所以王天泽大佬提供了一种极其暴力却暴打我nlogn的算法

不需要找最小公比,直接枚举1-1000,找到比就好了,400ms掉打你们

还是说一下我的思路(题解的)

首先一定是公比为1;直接扫一遍,找到最长的相等的子串就可以了

其次就是不为1::

  我们知道任何一个数都可以质因数分解

  我们设a[ ]为这个序列里的数

  x = a [ i ] ;  y = a [ i - 1 ];

  设x>y,只有当y整除x时才有可能构成等比数列

  设p=x/y

  我们对p进行质因数分解

  得到p1q1*p2q3*p3q3......

  那么还有一个性质:::

  设q为q1 q2 q3的最大公因数

  那么p为p1q1/q*p2q2/q*p3q3/q....的整数倍((这个显而易见))

  那么我们则mini=p1q1/q*p2q2/q*p3q3/q....即为x,y的最小公比(就是能够构成等比数列的最小的公比)::4=>2   8=>2    27=>3   216=>6

  这样预处理出来所有的mini(2-n)

  如果两个mini相等,那么就可以构成等比序列,当然不能有重复的

  这时候就要用上map大法了,就像数组一样用只不过下标可以直接开到longlong,

  每一个map都存着这个数出现的位置,更新的时候就方便多了

  

  

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll unsigned long long
const int N=100005;
int n;
ll a[N];
int ans=0,res=0;
ll prime[N],vis[N],cnt;
ll mini[N],q[N],ch[N];
ll st[N][120];
ll ksm(ll x,int y){
ll ret=1;
while(y){
if(y&1)ret=ret*x;
x=x*x;
y>>=1;
}
return ret;
}
ll gcd(ll x,ll y){
if(y==0)return x;
return gcd(y,y%x);
}
void getmin(ll x,ll y,int z){
if(x==0||y==0)return ;
if(x>y)swap(x,y);
ll p=y%x;
//cout<<z<<" "<<y<<" "<<x<<" "<<p<<"sb"<<endl;
if(p!=0){
mini[z]=0;
return ;
}
p=y/x;ch[z]=p;
//cout<<p<<endl;
for(re i=1;i<=cnt;i++){
q[i]=0;
while(p%prime[i]==0)
p/=prime[i],q[i]++;
}
int pd;
ll g;
for(re i=1;i<=cnt;i++){
if(q[i]==0)continue;
if(g==0){
g=q[i];
continue;
}
g=gcd(g,q[i]);
}
for(re i=1;i<=cnt;i++){
if(q[i]==0)continue;
mini[z]*=pow(prime[i],q[i]/g);
}
}
map<ll,int> mp;
int main(){
scanf("%d",&n);
for(re i=2;i<=1002;i++){
if(vis[i]==0)prime[++cnt]=i;
for(re j=1;j<=cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
mini[1]=0;
for(re i=2;i<=n;i++)mini[i]=1;
for(re i=1;i<=n;i++){
scanf("%lld",&a[i]);
if(a[i]==a[i-1])res++;
else res=1;
ans=max(ans,res);
getmin(a[i-1],a[i],i);
//cout<<i<<" "<<mini[i]<<endl;
}
int fro,beh;//前后端点
for(re i=2;i<=n;i++){
//while(mini[i-1]!=0&&ch[i]%mini[i-1]==0&&ch[i]!=0)ch[i]/=mini[i-1];
if(mini[i]==mini[i-1]&&mini[i]!=0){
if(mp[a[i]]&&mp[a[i]]>=fro)fro=mp[a[i]]+1;
mp[a[i]]=i;beh=i;
}
else{
mp.clear();
mp[a[i-1]]=i-1;
mp[a[i]]=i;
fro=i-1;
beh=i;
}
ans=max(ans,beh-fro+1);
}
printf("%d",ans);
}

code

T2熟练剖分

题目描述

为什么你们noip的时候shulian(树链)剖分敲得那么shulian(熟练)啊?

你们到底,敲了多少遍树链剖分了啊?

为了考察noip选手们对树链剖分的掌握是否足够熟练,liu_runda决定出个树链剖分题.

可是,SD_le并不认为所有准备联赛的选手都学过树链剖分,因为他自己就不会,liu_runda便决定简述一下这个算法:

本题中使用的树链剖分算法在一棵有根树上进行.根节点编号为1.每个节点有若干个儿子.

每个非叶节点有且仅有一个重儿子,其他儿子称作轻儿子. 重儿子和父亲之间的边称作重边,轻儿子和父亲之间的边称作轻边.

对一个节点进行一次”精彩操作”付出的时间代价是这个节点到根节点路径上的轻边数量.根节点自身进行精彩操作的代价一定是0.我们只关注最坏情况下的时间复杂度,求出每个节点进行一次精彩操作的代价,然后在这些代价中取最大值,就得到了这棵树此时的最坏时间复杂度.

在本题中,liu_runda决定考察选手对树链剖分的灵活应用,因此每一个非叶节点将在它的所有儿子中等概率随机选择一个作为重儿子.

给出一棵树,按上面的方式随机选择重儿子,求最坏时间复杂度的期望.期望一定是一个有理数,可以表示成a/b的形式(a,b均为整数).只需要输出a乘上b的逆元后对10^9+7取模的结果.

输入格式

第一行一个正整数n,表示有n个点。

接下来n行,每行有一个整数k,表示i号点有k个儿子,接下来k个整数表示它的所有儿子。

输出格式

一行一个整数ans。

样例

样例输入

【样例输入1】
4
2 2 3
0
1 4
0
【样例输出1】
1

样例输出

【样例输入2】
7
1 5
2 7 3
0
1 6
0
0
2 1 4
【样例输出2】
500000005

数据范围与提示

对于20%的数据 n<=20

对于另外10%的数据 保证是一条链

对于另外10%的数据 保证数据随机

对于另外5%的数据 所有边都连到了一个点上

对于另外15%的数据 保证是一棵完全二叉树

对于另外15%的数据 n<=300

对于100%的数据 n<=3000

hint

根节点不一定是1

这题20pts

考场上没别的心思--对着部分分就是一顿操作

考场下才想正解,说实话,这正解是真的玄乎;;;;;;;

什么树链剖分,分明就是概率期望

借着体面吓唬人

这个主要是求概率;

不妨设f [i] [j]为以i为根节点,目前遍历的儿子节点中,能让i的最大深度<=j的概率

好看出来由儿子向父亲转移

设h[j]为目前最大深度为j的概率(h[1]+h[2]+...+h[j]=f[i][j])

g[j]为目前重儿子深度<=j的概率     初值均为1(因为一开始都为0,前缀和一下都是1)

先循环选择哪一个为重儿子,再遍历每一个儿子,里面再套一层深度

分二种情况

  目前儿子等于重儿子

    h[i]=g[j]*(f[i][j]-f[i][j-1])+(g[j]-g[j-1])*f[i][j]-(f[i][j]-f[i][j-1])*(g[j]-g[j-1]);

    //重儿子等于j,轻儿子小于等于j//////重儿子小于等于j,轻儿子等于j

  重儿子不等于轻儿子

    看代码吧,和上面差不多

你可能会怀疑为什么每一个f[i][j]都是中间变量,在还没运算到最后结果时

就自己调用自己,为什么是正确的

因为,每一个f[i][j]都是由前面的儿子转移的,可以当作一开始没有儿子,后来一个一个的加进来,这样就好理解了

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
const int mod=1e9+7;
const int N=3005;
int n,m[N];
int to[N],nxt[N],head[N],rp;
int fa[N],root,siz[N];
ll inv[N];
void add_edg(int x,int y){
to[++rp]=y;
nxt[rp]=head[x];
head[x]=rp;
}
ll f[N][N],g[N],h[N];
void dfs(int x){
siz[x]=1;
int maxn=0;
for(re i=head[x];i;i=nxt[i]){
dfs(to[i]);
siz[x]+=siz[to[i]];
maxn=max(maxn,siz[to[i]]);
}
for(re i=head[x];i;i=nxt[i]){
for(re j=0;j<=n;j++)g[j]=1;
int u=to[i];
for(re j=head[x];j;j=nxt[j]){
int v=to[j];
for(re k=0;k<=siz[v];k++){
ll gs=g[k],fs=f[v][k];
if(k){
gs-=g[k-1];
fs-=f[v][k-1];
}
if(u==v)h[k]=(gs*f[v][k]%mod+fs*g[k]%mod-fs*gs%mod+mod)%mod;
else{
fs=f[v][k-1];
if(k>1)fs-=f[v][k-2];
h[k]=(g[k]*fs%mod+gs*f[v][k-1]%mod-fs*gs%mod+mod)%mod;
}
}
g[0]=h[0];
for(re k=1;k<=siz[v];k++)
g[k]=(g[k-1]+h[k])%mod;
}
for(re j=siz[x];j>=1;j--)g[j]=(g[j]-g[j-1]+mod)%mod;
for(re j=0;j<=siz[x];j++)f[x][j]=(f[x][j]+g[j]*inv[m[x]]%mod)%mod;
}
if(!head[x])f[x][0]=1;
for(re i=0;i<=siz[x];i++){
f[x][i]=(f[x][i]+f[x][i-1])%mod;
}
}
signed main(){
scanf("%d",&n);
inv[1]=inv[0]=1;
for(re i=2;i<=n;i++)
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
for(re i=1;i<=n;i++){
scanf("%d",&m[i]);
int son;
for(re j=1;j<=m[i];j++){
scanf("%d",&son);
fa[son]=i;
add_edg(i,son);
}
}
root=1;
while(fa[root])root=fa[root];
//cout<<root<<endl;
dfs(root);
ll ans=0;
for(re i=n;i>=1;i--){
ans=(ans+i*(f[root][i]-f[root][i-1]+mod)%mod)%mod;
}
printf("%lld",ans);
}

Code

T3建造游乐园

题目描述

在学生的联名提议下,HZ决定在校园内建造一个新型游乐场。

游乐场一共有n个项目,在不同的项目之间有一些走廊相连。

为了保证学生能顺利的游玩完游乐场的每个项目,一个建造方案需要满足以下的条件:

  1. 将游乐园抽象为一张图,把走廊视为无向边,整张图无重边,无自环。
  2. 可以通过恰好一次操作使得图中存在一条欧拉回路(从某个点出发经过所有边恰好一次并最终回到起点的路径),其中操作可以是添加一条不在图中的边或是删去一条图中的边。要求操作后的图仍满足条件1,且图中任意两点可以互相到达。

设计游乐场布局的任务被委托给了学生会会长小R,小R想先统计出所有的方案,但她数数向来数不清,所以你能不能帮小R统计一下一共有多少种建造方案。

输入格式

一行一个整数n,表示游乐园有n个项目。

输出格式

仅一行一个整数表示答案对1000000007取模的结果。

样例

样例输入

【输入样例1】
3
【输出样例1】
3

样例输出

【输入样例2】
9
【输出样例2】
21124449
【样例解释】
第一个样例三个合法的图分别是:
(1 ? 2),(2 ? 3)
(1? 2),(1?3)
(1 ? 3),(2 ? 3)

数据范围与提示

20% 的数据:n ≤ 10

60% 的数据:n ≤ 100

100% 的数据:2 ≤ n ≤ 2000

不是这个题简单是高俊垚大神讲的好(((呱叽呱叽)))

首先设f[n]为n个点时可以得到的联通欧拉图;

g[n]为n个点时可以得到的联不联通都行的;

那么最终答案就是ans=f[n]*Cn2

显然g[i]=2^Ci-12因为现在有一个i-1个点的随便一张图,那么要想让每一个点的度都为偶数

就要让第i个点连接那些奇数点这样一一对应得到了欧拉图

f[i]=g[i]-∑j(1-i-1)f[j]*g[i-j]*Ci-1j-1

这个式子怎么来的呢

减去的这一堆一定是不联通的那么肯定有很多个联通块

只需要找出两个就够了所以选出来几个数在外面

循环j(几个数在外面)

得到本式

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
const int mod=1e9+7;
const int N=2005;
int n;
ll jc[N],inv[N],innv[N];
ll f[N],g[N];
ll ksm(ll x,ll y){
ll ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;
y>>=1;
}
return ret%mod;
}
ll C(ll x,ll y){
if(x>y)return 0;
return jc[y]*inv[x]%mod*inv[y-x]%mod;
}
int main(){
scanf("%d",&n);
jc[1]=1;jc[0]=1;
inv[1]=inv[0]=1;
innv[1]=innv[0]=1;
for(re i=2;i<=n;i++){
jc[i]=jc[i-1]*i%mod;
innv[i]=(mod-mod/i)*innv[mod%i]%mod;
inv[i]=innv[i]*inv[i-1]%mod;
}
g[1]=1;
for(re i=2;i<=n;i++){
g[i]=ksm(2,C(2,i-1));
}
f[1]=1;
for(re i=2;i<=n;i++){
ll tmp=0;
for(re j=1;j<i;j++){
tmp=(tmp+f[j]*g[i-j]%mod*C(j-1,i-1)%mod)%mod;
}
f[i]=(g[i]-tmp+mod)%mod;
}
printf("%lld",f[n]*C(2,n)%mod);
}

Code

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define re register int
4 #define ll long long
5 const int mod=1e9+7;
6 const int N=2005;
7 int n;
8 ll jc[N],inv[N],innv[N];
9 ll f[N],g[N];
10 ll ksm(ll x,ll y){
11 ll ret=1;
12 while(y){
13 if(y&1)ret=ret*x%mod;
14 x=x*x%mod;
15 y>>=1;
16 }
17 return ret%mod;
18 }
19 ll C(ll x,ll y){
20 if(x>y)return 0;
21 return jc[y]*inv[x]%mod*inv[y-x]%mod;
22 }
23 int main(){
24 scanf("%d",&n);
25 jc[1]=1;jc[0]=1;
26 inv[1]=inv[0]=1;
27 innv[1]=innv[0]=1;
28 for(re i=2;i<=n;i++){
29 jc[i]=jc[i-1]*i%mod;
30 innv[i]=(mod-mod/i)*innv[mod%i]%mod;
31 inv[i]=innv[i]*inv[i-1]%mod;
32 }
33 g[1]=1;
34 for(re i=2;i<=n;i++){
35 g[i]=ksm(2,C(2,i-1));
36 }
37 f[1]=1;
38 for(re i=2;i<=n;i++){
39 ll tmp=0;
40 for(re j=1;j<i;j++){
41 tmp=(tmp+f[j]*g[i-j]%mod*C(j-1,i-1)%mod)%mod;
42 }
43 f[i]=(g[i]-tmp+mod)%mod;
44 }
45 printf("%lld",f[n]*C(2,n)%mod)

2021.5.22 noip模拟1的更多相关文章

  1. 8.22 NOIP 模拟题

      8.22 NOIP 模拟题 编译命令 g++ -o * *.cpp gcc -o * *.c fpc *.pas 编译器版本 g++/gcc fpc 评测环境 位 Linux, .3GHZ CPU ...

  2. 2018.9.22 NOIP模拟赛

    *注意:这套题目应版权方要求,不得公示题面. 从这里开始 Problem A 妹子 Problem B 旅程 Problem C 老大 因为业务水平下滑太严重,去和高一考NOIP模拟,sad... P ...

  3. 9.22 NOIP模拟题

    吉林省信息学奥赛 2017 冬令营                                                                                    ...

  4. 2018.08.22 NOIP模拟 string(模拟)

    string [描述] 给定两个字符串 s,t,其中 s 只包含小写字母以及*,t 只包含小写字母. 你可以进行任意多次操作,每次选择 s 中的一个*,将它修改为任意多个(可以是 0 个)它的前一个字 ...

  5. 7.22 NOIP模拟7

    又是炸掉的一次考试 T1.方程的解 本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判..暴力掉了40分. 首先a+b=c,只有一组解. 然后是a=1,b=1,答案是c-1 ...

  6. 9.22 noip模拟试题

    水灾(sliker.cpp/c/pas) 1000MS  64MB 大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY ...

  7. 2018.08.22 NOIP模拟 shop(lower_bound+前缀和预处理)

    Shop 有 n 种物品,第 i 种物品的价格为 vi,每天最多购买 xi 个. 有 m 天,第 i 天你有 wi 的钱,你会不停购买能买得起的最贵的物品.你需要求出你每天会购买多少个物品. [输入格 ...

  8. 2018.08.22 NOIP模拟 or(线段树)

    or [描述] 构造一个长度为 n 的非负整数序列 x,满足 m 个条件,第 i 个条件为x[li] | x[li+1] | - | x[ri]=pi. [输入] 第一行两个整数 n,m.接下来 m ...

  9. 18.9.22 noip模拟赛

    此题为找规律.期望100 实际100 #include<cstdio> #include<cstring> #include<iostream> #include& ...

随机推荐

  1. Shell-日志按天切割

    1.创建shell脚本: #!/bin/bash apphome=/apppath if [ ! -d $apphome ]; then exit 0 fi cp $apphome/app.log $ ...

  2. POJ1087DFS+匈牙利或者DINIC

    题意:      有n个插孔,m个电器,q种转换器(转换器可以无限用),然后问你最多有多少个电器能充电. 思路:       比较简单,就是在建图的时候要考虑下,我用了两种方法做的,一个是最大流,这个 ...

  3. Python脚本破解图形验证码(tesserocr和pytesseract)

    在学习之前,我们先了解OCR.tesseract.tesserocr.pytesseract和opencv这几个跟图片处理有关的库. OCR(Optical Character Recognition ...

  4. Intel汇编语言程序设计学习-第三章 汇编语言基础-上

    汇编语言基础 3.1  汇编语言的基本元素 有人说汇编难,有人说汇编简单,我个人不做评价,下面是一个简单的实例(部分代码): main PROC mov  eax,5  ;5送EAX寄存器 add   ...

  5. 【Git】3. Git重要特性-分支操作,合并冲突详解

    一.分支介绍 在版本控制过程当中,有时候需要同时推进多个任务,这样的话,就可以给每个任务创建单独的分支. 有了分支之后,对应的开发人员就可以把自己的工作从主线上分离出来,在做自己分支开发的时候,不会影 ...

  6. 【jQuery】精细学习记录

    [jQuery]精细学习记录 基础 基本语法: $(选择器).action(回调函数); $/jQuery //jQuery核心函数 $(选择器) //获得的jQuery对象 jQuery核心 - j ...

  7. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

  8. JVM默认内存大小

    堆(Heap)和非堆(Non-heap)内存 按照官方的说法:"Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在Java虚拟机启动时创建的." ...

  9. C#事件总线

    目录 简介 实现事件总线 定义事件基类 定义事件参数基类 定义EventBus 使用事件总线 事件及事件参数 定义发布者 定义订阅者 实际使用 总结 参考资料 简介 事件总线是对发布-订阅模式的一种实 ...

  10. (10)MySQL进阶篇SQL优化(InnoDB锁-间隙锁)

    1.概述 当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁:对于键值在条件范围内但并不存在的记录,叫做"间隙(GAP)&quo ...