前言

先吐槽一下出题人,T2 牛马数据连棵树都不是。。

T3 描述不清楚。。

T1 如何优雅的送分

解题思路

我考场上还真以为是个送分题,然而。。。

莫比乌斯反演。。。

对于一个数字 n 有 \(2^{F(n)}=\sum\limits_{d|n}\mu^2(d)\) ,由于有平方因子的数字的 \(\mu\) 的值是 0 ,就相当于在所有的质因数里面选择若干个质因数组合。

\(\mu^2(n)=\sum\limits_{d^2|n}\mu(d)\) 对于质数的情况是比较显然的,毕竟符合条件的只有 1 。

这个可以理解为枚举质因数的个数算对应的答案。

假设这个数质因数的个数是 \(cnt\) ,那么答案就是 \(\sum\limits_{i=0}^{cnt}(-1)^i\times \binom{cnt}{i}\) 由二项式定理可得上式为 0 。

于是答案就是 \(\displaystyle\sum_{i=1}^n 2^{F(i)}=\sum_{i=1}^n\sum_{d|i}\sum_{k^2|d}\mu(k)\)

更改枚举顺序 \(\displaystyle\sum_{k=1}^n\mu(k)\sum_{k^2|d}\lfloor\frac{n}{d}\rfloor\)

也就是 \(\displaystyle\sum_{k=1}^n\mu(k)\sum_{i=1}^{\lfloor\frac{n}{k^2}\rfloor}\lfloor\frac{n}{k^2i}\rfloor\)

设 \(S(n)=\sum\limits_{i=1}^n\lfloor \frac{n}{i}\rfloor\) 上述柿子就是 \(\sum\limits_{k=1}^n \mu(k)S(\lfloor\frac{n}{k^2}\rfloor)\) 。

对于 \(S\) 的运算可以数论分块 复杂度是 \(\mathcal{O}(\sqrt{n}logn)\)

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e6+7,mod=1e9+7;
int n,m,ans,cnt,pri[N],mu[N];
bool vis[N];
void Pre_work()
{
mu[1]=1;
for(int i=2;i<=m;i++)
{
if(!vis[i]) pri[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&pri[j]*i<=m;j++)
{
int temp=i*pri[j]; vis[temp]=true;
if(i%pri[j]==0){mu[temp]=0;break;}
mu[temp]=-mu[i];
}
}
}
int S(int lim)
{
int sum=0;
for(int l=1,r;l<=lim;l=r+1)
{
r=lim/(lim/l);
sum=(sum+lim/l%mod*(r-l+1)%mod)%mod;
}
return sum;
}
signed main()
{
freopen("elegant.in","r",stdin); freopen("elegant.out","w",stdout);
n=read(); m=sqrt(n)+1; Pre_work();
for(int i=1;i<=n;i++)
{
int temp=S(n/(i*i));
if(!temp) break;
ans=(ans+mu[i]*temp%mod+mod)%mod;
}
printf("%lld",ans);
return 0;
}

T2 阴阳

解题思路

正解不太会,打了个暴力,可能是由于数据水,骗到了 100pts (虽然后来被Hack成了 91pts)

比较好奇的就是出题人的数据怎么造的(原来 n 个点 n-1 条边还可以是有环的森林。。。)

暴力思路比较简洁,我们需要一个可以动态开空间并且支持查找并且删掉某一个值的数据结构,unoedered_set 刚好可以满足我们的需求。

于是我们可以维护每一个版本的所有黑色节点,每次暴扫整个 set 求出答案。

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e5+10,M=3e3+10,INF=1e9;
int typ,n,m,t,ans,cnt,now,s[N];
int tot=1,head[N],ver[N<<1],nxt[N<<1];
int tim,dfn[N],siz[N],fa[N],son[N],dep[N],topp[N];
unordered_set<int> res[N];
void add_edge(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i]; if(siz[to]) continue;
fa[to]=x; dep[to]=dep[x]+1;
dfs1(to); siz[x]+=siz[to];
if(siz[to]>siz[son[x]]) son[x]=to;
}
}
void dfs2(int x,int tp)
{
topp[x]=tp; dfn[x]=++tim;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i;i=nxt[i])
if(!dfn[ver[i]])
dfs2(ver[i],ver[i]);
}
int LCA(int x,int y)
{
while(topp[x]^topp[y])
{
if(dep[topp[x]]<dep[topp[y]]) swap(x,y);
x=fa[topp[x]];
}
if(dep[x]>dep[y]) swap(x,y);
return x;
}
int dist(int x,int y){return dep[x]+dep[y]-2*dep[LCA(x,y)];}
signed main()
{
freopen("yygq.in","r",stdin); freopen("yygq.out","w",stdout);
typ=read(); n=read();
for(int i=1,x,y;i<n;i++)
x=read(),y=read(),
add_edge(x,y),add_edge(y,x);
dfs1(1); dfs2(1,1); m=read();
while(m--)
{
int opt,x; opt=read(); x=read()^(typ*ans);
if(opt==1)
{
cnt++; res[cnt]=res[now];
if(res[now].find(x)==res[now].end()) res[cnt].insert(x);
else res[cnt].erase(x); now=cnt; continue;
}
if(opt==2)
{
ans=INF;
for(auto it:res[now]) ans=min(ans,dist(x,it));
printf("%lld\n",ans); continue;
}
now=x;
}
return 0;
}

T3 你猜是不是找规律

解题思路

我还真就以为是个找规律了。。。

出题人描述不清楚,题目认为的有序序列只是一种顺序只能是升序或者只能是降序。

DP 转移 \(f_{i,j}\) 表示对于有序的序列前 i 个数字交换 j 次可以得到的不同序列。

就有方程:\(f_{i,j}=f_{i-1,j}+f_{i-1,j-1}\times(i-1)\) 。

然后发现其实前缀和是一个有 \(2k\) 项的多项式(我也不知道为啥是这个。。),然后直接拉格朗日插值。。

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=3e3+10,mod=1e9+7;
int n,m,ans,f[2][N],s[N<<1];
int power(int x,int y,int p=mod)
{
int temp=1;
while(y)
{
if(y&1) temp=temp*x%p;
x=x*x%p; y>>=1;
}
return temp;
}
void solve1()
{
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++) f[i&1][j]=f[(i&1)^1][j];
for(int j=1;j<=min(i,m);j++) f[i&1][j]=(f[i&1][j]+(i-1)*f[(i&1)^1][j-1])%mod;
}
for(int i=0;i<=m;i++) ans=(ans+f[n&1][i])%mod;
printf("%lld",ans); exit(0);
}
signed main()
{
freopen("guess.in","r",stdin); freopen("guess.out","w",stdout);
n=read(); m=read(); f[0][0]=1;
if(n<=3000) solve1();
for(int i=1;i<=2*m+1;i++)
{
for(int j=0;j<=m;j++) f[i&1][j]=f[(i&1)^1][j];
for(int j=1;j<=min(i,m);j++)
f[i&1][j]=(f[i&1][j]+(i-1)*f[(i&1)^1][j-1])%mod;
for(int j=0;j<=m;j++) s[i]=(s[i]+f[i&1][j])%mod;
}
for(int i=1;i<=2*m+1;i++)
{
int temp=1,base=1;
for(int j=1;j<=2*m+1;j++)
if(i!=j)
temp=(n-j+mod)%mod*temp%mod,
base=base*(i-j+mod)%mod;
ans=(ans+s[i]*temp%mod*power(base,mod-2))%mod;
}
printf("%lld",ans);
return 0;
}

T4 小说

解题思路

运用退背包每次枚举退掉的点,选择造成损失比较小的,方案可以在对于大质数取模的意义下考虑。

然后有了这个去掉的物品,接下来我们所选择的 b 不可以被剩下物品 \(v_i,-v_i\) 构成。

对于剩下的物品按上面两个值做一个 01背包,取大于 0 的第一个值作为答案。

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=110,M=7e5+10,mod=1e9+7,base=7e5+10;
int n,lim,ans,maxn,id,s[N],f[M],g[M];
bitset<(M<<1)> bit;
signed main()
{
freopen("novel.in","r",stdin); freopen("novel.out","w",stdout);
n=read(); f[0]=1; for(int i=1;i<=n;i++) s[i]=read(),lim+=s[i];
for(int i=1;i<=n;i++)
for(int j=lim;j>=s[i];j--)
f[j]=(f[j]+f[j-s[i]])%mod;
for(int i=1;i<=n;i++)
{
int sum=0;
for(int j=0;j<=lim;j++) g[j]=f[j];
for(int j=s[i];j<=lim;j++) g[j]=(g[j]-g[j-s[i]]+mod)%mod;
for(int j=1;j<=lim;j++) sum+=(g[j]>0);
if(sum>maxn) maxn=sum,id=i;
}
bit[base]=true;
for(int i=1;i<=n;i++) if(i!=id) bit|=bit>>s[i],bit|=bit<<s[i];
for(int i=1;i<=lim+1;i++) if(!bit[i+base]){ans=i;break;}
printf("%lld %lld",s[id],ans);
return 0;
}

NOIP模拟75的更多相关文章

  1. Noip模拟75 2021.10.12

    T1 如何优雅的送分 他说是送分题,我就刚,没刚出来,想到莫比乌斯容斥后就都没推出来 好吧还是不能被恶心的题目,挑衅的语言打乱做题节奏 于是这一场也就没了.... $F(i)$表示$i$的不同质因子集 ...

  2. 2021.10.12考试总结[NOIP模拟75]

    T1 如何优雅的送分 考虑式子的实际意义.\(2^{f_n}\)实际上就是枚举\(n\)质因子的子集.令\(k\)为这个子集中数的乘积,就可以将式子转化为枚举\(k\),计算\(k\)的贡献. 不难得 ...

  3. 2019.7.29 NOIP模拟测试10 反思总结【T2补全】

    这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...

  4. NOIP模拟17.9.22

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

  5. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  6. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  7. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  8. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  9. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  10. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

随机推荐

  1. 重新点亮linux 命令树————守护进程[二十三]

    前言 简单整理一下守护进程. 正文 守护进程一般是开机启动的. 使用nohup 与 & 符号配合运行一个命令 nohup命令使进程忽略hangup(挂起)信号 使用tail 查看log文件. ...

  2. 重新整理.net core 计1400篇[七] (.net core 中的依赖注入)

    前言 请阅读第六篇,对于理解.net core 中的依赖注入很关键. 和我们上一篇不同的是,.net core服务注入保存在IServiceCollection 中,而将集合创建的依赖注入容器体现为I ...

  3. RestfulApi 学习笔记——分页和排序(六)

    前言 分页和排序时一些非常常规的操作,同样也有一些我们注意的点. 正文 分页 先来谈及分页. 看下前端传递的参数. public class EmployeeDtoParameters { priva ...

  4. etcd 历史版本回溯的方法

    在使用 etcd 作为配置存储或者其他的场景,如果因为误操作对其中 key 的值进行了修改,如果想要找回原来的值,可以利用 etcd 的版本机制进行回溯找回以前的值.在具体操作之前,我们首先获取一下 ...

  5. PyQt 快速使用

    1.安装 PyQt:使用 pip 命令在终端或命令提示符中运行以下命令: pip install pyqt5 2.创建 PyQt 应用程序:导入 PyQt5 模块并创建一个 QApplication ...

  6. 力扣206(java&python)-反转链表(简单)

    题目: 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表. 示例1: 输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1] 示例2: 输入:head = [1,2] ...

  7. 混合云K8s容器化应用弹性伸缩实战

    简介: 混合云K8s容器化应用弹性伸缩实战 1. 前提条件 本最佳实践的软件环境要求如下:应用环境:①容器服务ACK基于专有云V3.10.0版本.②公共云云企业网服务CEN.③公共云弹性伸缩组服务ES ...

  8. [PHP] Laravel-admin 模型表格-列的显示-链接: 关联关系的跳转链接

    link 将字段显示为一个链接. // link方法不传参数时,链接的`href`和`text`都是当前列的值 $grid->column('homepage')->link(); // ...

  9. Codeforces Good Bye 2023

    A. 2023 正常签到. void solve() { int n, k, ok = 1; cin >> n >> k; int t = 2023; while(n --) ...

  10. Redis官方开源的可视化管理工具 - RedisInsight

    前言 今天大姚给大家推荐一款Redis官方开源的可视化管理工具:RedisInsight. Redis介绍 Redis (Remote Dictionary Server) 是一个使用 C 语言编写的 ...