NOIP模拟测试17&18

17-T1

给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是?

特判比值为1的情况,预处理比值2~1000的幂,存map里。接下来枚举左端点,算出比值,枚举右端点,用平衡树便携判断某个数是否已经在区间内出现过。

#include<bits/stdc++.h>
using namespace std;
inline long long read()
{
long long x=0,fh=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=(x<<1LL)+(x<<3LL)+(ch^48LL);ch=getchar();}
return x*fh;
}
const int maxn=1e5+5;
const int mod=1e5+3;
const long long INF=1000000000000000000ll;
map<long long,int> fr;
long long a[maxn],mmax,mmin;
int ans=1,h[maxn],tot=1,n;
struct hash{
int num,nxt;
long long val;
}b[maxn<<4];
set<long long> s;
int main(){
for(unsigned long long i=1000;i>=2;i--)
{
for(unsigned long long j=i;j<=INF;j*=i)
{
if(j==0)
break;
fr[(long long)j]=i;
}
}
memset(h,-1,sizeof(h));
n=read();
long long lat=0;
int cnt=0;
for(int i=1;i<=n;i++){
a[i]=read();
if(a[i]==lat)
{
cnt++;
}
else
{
lat=a[i];
cnt=1;
}
ans=max(ans,cnt);
}
for(int l=1;l<n;l++)
{
s.clear();
s.insert(a[l]);
mmax=max(a[l],a[l+1]);
mmin=min(a[l],a[l+1]);
if(mmin==mmax || mmax%mmin)
continue;
s.insert(a[l+1]);
int gys=fr[mmax/mmin];
ans=max(ans,2);
for(int r=l+2;r<=n;r++){
if(s.find(a[r])!=s.end())
break;
s.insert(a[r]);
mmax=max(a[r],a[r-1]);
mmin=min(a[r],a[r-1]);
if(mmax%mmin!=0)
break;
if(fr[mmax/mmin]!=gys)
break;
ans=max(ans,r-l+1);
}
}
printf("%d\n",ans);
return 0;
}

17-T2

对一个节点进行一次”精彩操作”付出的时间代价是这个节点到根节点路径上的轻边数量.

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

每一个非叶节点将在它的所有儿子中等概率随机选择一个作为重儿子.给出一棵树,按上面的方式随机选择重儿子,求最坏时间复杂度的期望 \(mod1e9+7\)

设 \(f[i][j]\) 为以ii为根节点的子树中最坏时间复杂度小于等于jj的概率设 \(g[i][j]\) 为当前扫到的以ii为父亲节点的所有儿子最坏时间复杂度小于等于 \(j\) 的概率之和.

枚举当前哪一个节点充当重儿子、所有儿子、枚举最坏时间复杂度 \(k\).

如果第二重循环中枚举的儿子恰好是重儿子的话,那么父亲节点的最坏时间复杂度为 \(k\) 的情况可以由两种情况转移过来.

1.重儿子的时间复杂度恰好为 \(k\) 的概率乘上其它儿子时间复杂度小于等于 \(k\) 的概率

2.其它儿子的时间复杂度恰好为 \(k\) 的概率乘上重儿子的时间复杂度小于等于 \(k\) 的概率.


#include<bits/stdc++.h>using namespace std;const int N=5000,M=10000,mod=1e9+7;struct bian{
int nxt,to;}b[M];int head[N],cnt,n,son[N],fa[N],root=1,siz[N];long long ans,f[N][N],g[N],h[N];void add(int from,int to){
b[++cnt].nxt=head[from];
b[cnt].to=to;
head[from]=cnt;}int qp(int a,int b){
int rec=1;
while(b>0)
{
if(b&1)
{
rec=1LL*rec*a%mod;
}
a=1LL*a*a%mod;
b>>=1;
}
return rec;}void dfs(int u){
siz[u]=1;
int i=head[u],v;
while(i)
{
v=b[i].to;
if(v!=fa[u])
{
dfs(v);
siz[u]+=siz[v];
}
i=b[i].nxt;
}
int p=qp(son[u],mod-2);
i=head[u];
while(i)
{
v=b[i].to;
if(v==fa[u])
{
i=b[i].nxt;
continue;
}
for(int j=0;j<=n;j++)
g[j]=1;
int j=head[u],v2;
while(j)
{
v2=b[j].to;
if(v2==fa[u])
{
j=b[j].nxt;
continue;
}
for(int k=0;k<=siz[v2]+1;k++)
{
long long qt=g[k],xz=f[v2][k];
if(k)
{
qt-=g[k-1];
xz-=f[v2][k-1];
}
if(v==v2)
{
h[k]=(qt*f[v2][k]%mod+xz*g[k]%mod-xz*qt%mod+mod)%mod;
}
else
{
xz=f[v2][k-1];
if(k>1)
xz-=f[v2][k-2];
h[k]=(qt*f[v2][k-1]%mod+xz*g[k]%mod-xz*qt%mod+mod)%mod;
}
}
g[0]=h[0],h[0]=0;
for(int k=1;k<=siz[v2]+1;k++)
{
g[k]=(g[k-1]+h[k])%mod;
h[k]=0;
}
j=b[j].nxt;
}
for(int j=siz[u];j>=1;j--)
{
g[j]=(g[j]-g[j-1]+mod)%mod;
}
if(u==1)
{
int xxx;
xxx++;
}
for(int j=0;j<=siz[u];j++){
f[u][j]=(f[u][j]+g[j]*p%mod)%mod;
}
i=b[i].nxt;
}
if(son[u]==0)
f[u][0]=1;
for(int i=1;i<=siz[u]+1;i++)
{
f[u][i]=(f[u][i]+f[u][i-1])%mod;
}}int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&son[i]);
for(int j=1,v;j<=son[i];j++)
{
scanf("%d",&v);
fa[v]=i;
add(i,v);
add(v,i);
}
}
while(fa[root])
root=fa[root];
dfs(root);
for(int i=1;i<=n;i++)
{// cout<<i<<" "<<f[root][i]<<" "<<f[root][i-1]<<endl;
ans=(ans+1LL*i*(f[root][i]-f[root][i-1]+mod)%mod+mod)%mod;
}
printf("%lld\n",ans);
return 0;}

17-T3

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

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

为了保证学生能顺利的游玩完游乐场的每个项目,一个建造方案需要满足以下的条件:将游乐园抽象为一张图,把走廊视为无向边,整张图无重边,无自环。可以通过恰好一次操作使得图中存在一条欧拉回路(从某个点出发经过所有边恰好一次并最终回到起点的路径),其中操作可以是添加一条不在图中的边或是删去一条图中的边。要求操作后的图仍满足条件1,且图中任意两点可以互相到达。设计游乐场布局的任务被委托给了学生会会长小R,小R想先统计出所有的方案,但她数数向来数不清,所以你能不能帮小R统计一下一共有多少种建造方案。

一句话题意:求 \(n\)个点任意连无向边组成的欧拉回路种类乘\(C_{n}^{2}\)

引理

1.无向连通图奇数出度的点个数为偶数.

2.度数均为偶数的无向联通图为欧拉回路.

设:

\(f[i]\) 表示 \(i\) 个点任意连无向边组成的欧拉回路种类.

\(g[i]\) 表示 \(i-1\) 个点任意连无向边组成的图种类.显然有 \(g[i]=2^{C_{i}^{2}}\)

\(i-1\) 个点的无向连通图向 \(i\) 点连成欧拉回路的充要条件是,将原图中奇数出度的点与 \(i\) 点连接。

我们运用容斥,\(f[i]=g[i]-\sum_{j=1}^{i-1}f[j]g[i-j]C_{i-1}^{j-1}\)

(总情况减去不连通的)

#include<bits/stdc++.h>
#define N 5000
using namespace std;
const int mod=1e9+7;
inline int read()
{
int s=0,w=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
return s*w;
}
int n;
long long C[N][N],p[N],f[N];
long long qp(long long a,long long b)
{
long long rec=1;
while(b>0)
{
if(b&1)
{
rec*=a;
rec%=mod;
}
a*=a;
a%=mod;
b>>=1;
}
return rec;
}
int main()
{
n=read();
for(int i=0;i<=n;i++)
C[i][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
// for(int i=1;i<=n;i++)
// {
// for(int j=1;j<=i;j++)
// {
// printf("%lld ",C[i][j]);
// C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
// }
// puts("");
// }
for(int i=1;i<=n;i++)
p[i]=qp(2,C[i-1][2]);
for(int i=1;i<=n;i++)
{
long long sum=0;
f[i]=p[i];
for(int j=1;j<=i-1;j++)
{
f[i]-=f[j]*p[i-j]%mod*C[i-1][j-1]%mod;
f[i]%=mod;
}
f[i]=((f[i]%mod+mod)%mod+mod)%mod;
}
printf("%lld\n",((f[n]*C[n][2]%mod+mod)%mod+mod)%mod);
return 0;
}
/*
欧拉回路:无向图的每个节点的度数都是偶数度
无向图奇数度的点一定为偶数
n^2递推,f[i]表示i个点的欧拉回路最终图种类数
最终答案为f[n]*C[n][2]
不合法的转移
j个点的欧拉回路
*/

18-T1


#include<bits/stdc++.h>
using namespace std;
const int M=400000,N=200000;
inline int read()
{
    int s=0,w=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
int n,m,cnt,head[N],du[N],zh[N],sumzh;
bool vis[N];
long long ans;
struct bian
{
    int nxt,to;
}b[M];
void add(int from,int to)
{
    b[++cnt].nxt=head[from];
    b[cnt].to=to;
    head[from]=cnt;
}
void dfs(int u,int fa)
{
    vis[u]=1;
    int i=head[u],v;
    while(i)
    {
        v=b[i].to;
        if(!vis[v]&&v!=fa)
        {
            dfs(v,u);
        }
        i=b[i].nxt;
    }
}
int main()
{
    n=read();
    m=read();
    for(int i=1,u,v;i<=m;i++)
    {
        u=read();v=read();
        if(u==v)
        {
            sumzh++;
            zh[u]++;
            continue;
        }
        add(u,v);
        add(v,u);
        du[u]++;
        du[v]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(!vis[i]&&du[i])
        {
            dfs(i,0);
            break;
        }
    }
    bool ok=0;
    for(int i=1;i<=n;i++)
    {
        if(vis[i])
        {
            ok=1;
            break;
        }
    }
    if(ok==0)
        du[1]=1;
    for(int i=1;i<=n;i++)
    {
        if(!vis[i]&&du[i])
        {
            printf("0\n");
            return 0;
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=head[i];j;j=b[j].nxt)
        {
            ans+=du[b[j].to]-1;
        }
    }
    for(int i=1;i<=n;i++)
    {
        ans+=du[i]*sumzh;
    }
    ans+=sumzh*(sumzh-1);
    ans/=2;
    printf("%lld\n",ans);
    return 0;
}
/*
显然起点和重点必须有一条直走一次的边,否则无法走出去
m-2条边允许走2次,把所有边复制一倍,一定欧拉回路
从任何一个点出发,最后回退两条边一定满足目的
答案就是最后推掉的两条边种类
和路上一个自环只走一次的种类*退掉一条边
和路上两个自环只走一次 
非连通图直接白给 
*/ 

18-T2



#include<bits/stdc++.h>
using namespace std;
int n;
long long k,a[1000001],sum,maxn,ans;
int main()
{
    scanf("%d%lld",&n,&k);
    sum=k;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        sum+=a[i];
        maxn=max(maxn,a[i]);
    }
    maxn+=k;
    long long d=1;
    while(1)
    {
        long long flag=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]%d!=0)
                flag+=(a[i]/d+1)*d;
            else
                flag+=a[i];
        }
        if(flag<=sum)
            ans=d;
        if(maxn<=d)
            break;
        d=sum/(sum/(d+1));
    }
    cout<<ans<<endl;
    return 0;
}
//https://www.cnblogs.com/wwlwQWQ/p/11408950.html

18-T3



设:

\(f[i][j]\) 为i级的超级树有j条路径且无公共点的方案数

则有:

\[\begin{eqnarray} \\&
f[i+1][j+k]=\sum f[i][j]*f[i][k] \\&
f[i+1][j+k+1]=\sum f[i][j]*f[i][k] \\&
f[i+1][j+k]=\sum f[i][j]*f[i][k]*2*(j+k) \\&
f[i+1][j+k-1]=\sum f[i][j]*f[i][k]*C_{j+k}^{2} \\&
\end{eqnarray}\]

以上四种情况分别对应:

1.左子树和右子树不选根节点本身的路径,再加上原本的方案

2.左子树和右子树,选根节点本身的路径,再加上原本的方案

3.左子树的路径连接根节点,右子树的路径连接根节点

连接根节点有两种方案,即从一条路径的头连或者尾连,即根节点作为七点还是终点。所以要乘二。

4.左子树的路径经过根节点连接右子树的路径


#include<bits/stdc++.h>
using namespace std;
unsigned long long f[400][400],n,mod;
int main()
{
    scanf("%llu%llu",&n,&mod);
    f[1][0]=f[1][1]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=(n-i+2);j++)
        {
            for(int k=0;k<=(n-i+2-j);k++)
            {
                f[i+1][j+k]=(f[i+1][j+k]+f[i][j]*f[i][k]%mod)%mod;
                f[i+1][j+k+1]=(f[i+1][j+k+1]+f[i][j]*f[i][k]%mod)%mod;
                f[i+1][j+k]+=f[i][j]*f[i][k]%mod*2%mod*(j+k)%mod;
                f[i+1][j+k]%=mod;
                f[i+1][j+k-1]+=f[i][j]*f[i][k]%mod*(j+k)%mod*(j+k-1)%mod;
                f[i+1][j+k-1]%=mod;
            }
        }
    }
    printf("%llu\n",f[n][1]%mod);
    return 0;
}

NOIP模拟测试17&18的更多相关文章

  1. 8.11 NOIP模拟测试17 入阵曲+将军令+星空

    T1 入阵曲 前缀和维护可以得60分 f[x1][y1][x2][y2]=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];  O(n4) ...

  2. NOIP模拟测试17

    T1:入阵曲 题目大意:给定一个N*M的矩形,问一共有多少个子矩形,使得矩形内所有书的和为k的倍数. 60%:N,M<=80 枚举矩形的左上角和右下角,用二维前缀和求出数字之和. 时间复杂度$O ...

  3. NOIP模拟测试17「入阵曲&#183;将军令&#183;星空」

    入阵曲 题解 应用了一种美妙移项思想, 我们先考虑在一维上的做法 维护前缀和$(sum[r]-sum[l-1])\%k==0$可以转化为 $sum[r]\% k==sum[l-1]\%k$开个桶维护一 ...

  4. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  5. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  6. 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色

    2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...

  7. 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)

    2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

  8. 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】

    [题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...

  9. NOIP模拟测试1(2017081501)

    好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...

随机推荐

  1. SAS 常用字符串函数

    原文链接:https://www.cnblogs.com/snoopy1866/p/15085466.html CAT(item-1 <, -, item-n>) : 在保留首尾空格的情况 ...

  2. chanakya

    仅供个人娱乐 参考http://www.saulgoodman.cn/HA-Chanakya.html 靶机信息 https://www.vulnhub.com/entry/ha-chanakya,3 ...

  3. 8.3考试总结(NOIP模拟19)[最长不下降子序列·完全背包问题·最近公共祖先]

    一定要保护自己的梦想,即使牺牲一切. 前言 把人给考没了... 看出来 T1 是一个周期性的东西了,先是打了一个暴力,想着打完 T2 T3 暴力就回来打.. 然后,就看着 T2 上头了,后来发现是看错 ...

  4. SpringBoot | 3.3 整合MyBatis-Plus

    目录 前言 1. 什么是MyBatis-Plus 1.1 BaseMapper接口 1.2 IService接口 2. 整合MyBatis-Plus以及CRUD功能 2.1 导入场景依赖 2.2 CR ...

  5. 【大咖直播】Elastic Security 安全管理实战工作坊

    本次实战课程,旨在用 Elastic Security 来武装每一位安全运维人员,从容预防.检测和应对网络威胁.这款免费开放的解决方案提供了 SIEM.端点安全.威胁狩猎.云监控.恶意软件保护等功能. ...

  6. 盘点 HashMap 的实现原理及面试题

    1.请你谈谈 HashMap 的工作原理如果被问到 HashMap 相关的问题,它的工作原理都会被作为面试的开场白,这个时候先装作若有所思的样子冷静一下.首先 HashMap 是基于 hashing ...

  7. 获取sim 卡的IMEI 和 IMSI

    IReadOnlyList<string> networkAccIds = Windows.Networking.NetworkOperators.MobileBroadbandAccou ...

  8. MVVMLight学习笔记(五)---RelayCommand深究

    一.概述 有时候,单纯的命令绑定不一定能满足我们的开发需求,比如我们需要在命令绑定的时候传递一个参数,这个时候,我们就需要使用RelayCommand的泛型版本了. RelayCommand的泛型版本 ...

  9. 【java虚拟机】内存溢出解决思路

    转自:https://blog.csdn.net/u013521220/article/details/79523633 内存溢出与数据库锁表的问题,可以说是开发人员的噩梦,一般的程序异常,总是可以知 ...

  10. Linux下的Shell工作原理

    Linux下的Shell工作原理 Linux系统提供给用户的最重要的系统程序是Shell命令语言解释程序.它不属于内核部分,而是在核心之外,以用户态方式运行.其基本功能是解释并执行用户打入的各种命令, ...