7.28考试总结(NOIP模拟26)[神炎皇·降雷皇·幻魔皇]
或许只需一滴露水,便能守护这绽放的花朵。
前言
疯狂挂分,本来T2是想用树状数组优化一下的不知道为啥后来看了一下就少看了一层循环,
然后就想,我都 n 的复杂度了,足以搞过第一问了,还优化啥呀。。。。
在然后就挂了 20pts。。。。
后来一看 T3 的斐波那契数列,就上头,最后不仅正解没搞出来,就连 40pts 的暴力也没打,裂开。
对这次考试感觉比较特别的就是每个题的名字了。。
T1 神炎皇
解题思路
这题考场上是直接开始了找规律,发现从 1 到 n 的每一个有平方因子的数都会产生其最大平方因子开方后减一的贡献。
假设最大平方因子为 x ,贡献就是 \(\sqrt{x}-1\)
然后对于所有的都可以 n 的复杂度推出来,这样就有了 60pts (其实可以优化到 80pts)
枚举 \(\gcd(a,b)=d\) ,设\(a'=\dfrac{a}{d}\),\(b'=\dfrac{b}{d}\)
然后就有了\((a'+b')d\;|\;a'\times b'\times d^2\)。
因为\(\gcd(a',b')=1\)所以\(a'+b'\)一定是 d 的因数。
接下来就可以枚举\((a'+b')=k\) 那么合法的 d 就有 \(\dfrac{n}{k^2}\) 种取值。
毕竟\((a‘+b')\times d\le n\) 并且 \((a'+b')|d\)
合法的 (a',b') 有\(\phi(k)\)对,因为,\(a'+b'=k\)嘛。。。
直接线性筛搞出来之后直接算就行
code
60pts
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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=1e7+10,M=1e4+10;
int n,top,ans,sta[M];
int vis[N];
void init()
{
for(int i=2;i*i<=n;i++)
sta[++top]=i,vis[i*i]=i;
for(int i=2;i<=n;i++)
{
if(vis[i]) continue;
for(int j=1;j<=top&&sta[j]*sta[j]*i<=n;j++)
vis[sta[j]*sta[j]*i]=sta[j];
if(i*4>n) break;
}
}
signed main()
{
n=read();
init();
for(int i=1;i<=n;i++)
if(vis[i])
ans+=vis[i]-1;
printf("%lld",ans);
return 0;
}
正解
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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=1e7+10;
int n,m,ans,cnt,f[N],phi[N],pri[N];
bool vis[N];
void init()
{
phi[1]=1;
for(int i=2;i<=m;i++)
{
if(!vis[i])
{
pri[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt&&pri[j]*i<=m;j++)
{
vis[i*pri[j]]=true;
if(i%pri[j]==0)
{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
}
signed main()
{
n=read();
m=sqrt(n);
init();
for(int i=2;i<=m;i++)
ans+=phi[i]*(n/(i*i));
printf("%lld",ans);
return 0;
}
T2 降雷皇
解题思路
就一大水题。。。
第一问比较好求,直接树状数组优化就可以了,打法大概和树状数组求逆序对有些相似。
第二问对于暴力的柿子进行线段树优化,每次求解的时候传过来两个值。
一个是区间的最大值,以及对应的方案数。
继承的时候如果两个子区间的最大值相同,方案数就是加和,否则就是较大值的方案数。
实现上有一些细节问题,但也不是特别难调,算是比较水的一个题了。
code
40pts裸的暴力 DP
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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,mod=123456789;
int n,task,ans,answer,s[N],f[N],siz[N];
signed main()
{
n=read();
task=read();
for(int i=1;i<=n;i++)
s[i]=read();
fill(f+1,f+n+1,1);
siz[0]=1;
for(int i=2;i<=n;i++)
for(int j=1;j<i;j++)
if(s[j]<s[i])
f[i]=max(f[i],f[j]+1);
for(int i=1;i<=n;i++)
ans=max(f[i],ans);
printf("%lld",ans);
if(!task) return 0;
for(int i=1;i<=n;i++)
for(int j=0;j<i;j++)
if(f[j]+1==f[i]&&s[i]>s[j])
siz[i]=(siz[i]+siz[j])%mod;
for(int i=1;i<=n;i++)
if(f[i]==ans)
answer=(answer+siz[i])%mod;
printf("\n%lld",answer);
return 0;
}
正解
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define ls t[x].l
#define rs t[x].r
#define f() cout<<"Pass"<<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,mod=123456789;
int n,cnt,task,all,ans,answer,root,lsh[N],s[N],f[N],siz[N];
int tre[N];
struct VOP_Segment_Tree
{
int l,r,dat,val;
}t[N*80];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int num)
{
for(int i=x;i<=cnt;i+=lowbit(i))
tre[i]=max(tre[i],num);
}
int ask(int x)
{
int temp=0;
for(int i=x;i;i-=lowbit(i))
temp=max(temp,tre[i]);
return temp;
}
void push_up(int x)
{
t[x].val=max(t[ls].val,t[rs].val);
if(t[ls].val==t[rs].val)
t[x].dat=t[ls].dat+t[rs].dat;
else t[x].dat=(t[ls].val>t[rs].val)?t[ls].dat:t[rs].dat;
}
void insert(int &x,int l,int r,int pos,int val1,int val2)
{
if(!x) x=++all;
if(l==r)
{
if(t[x].val==val1) t[x].dat+=val2;
else t[x].dat=(t[x].val>val1)?t[x].dat:val2;
t[x].val=max(t[x].val,val1);
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) insert(ls,l,mid,pos,val1,val2);
else insert(rs,mid+1,r,pos,val1,val2);
push_up(x);
}
pair<int,int> query(int x,int l,int r,int L,int R)
{
if(L<=l&&r<=R) return make_pair(t[x].val,t[x].dat);
int mid=(l+r)>>1;
pair<int,int> tmp1=query(ls,l,mid,L,R),tmp2,temp;
tmp1.second%=mod;
if(R>mid) tmp2=query(rs,mid+1,r,L,R);
else return tmp1;
temp.first=max(tmp1.first,tmp2.first);
if(tmp1.first==tmp2.first)
temp.second=tmp1.second+tmp2.second;
else temp.second=(tmp1.first>tmp2.first)?tmp1.second:tmp2.second;
temp.second%=mod;
return temp;
}
signed main()
{
n=read();
task=read();
for(int i=1;i<=n;i++)
lsh[i]=s[i]=read();
sort(lsh+1,lsh+n+1);
cnt=unique(lsh+1,lsh+n+1)-lsh-1;
for(int i=1;i<=n;i++)
s[i]=lower_bound(lsh+1,lsh+cnt+1,s[i])-lsh;
fill(f+1,f+n+1,1);
siz[0]=1;
for(int i=1;i<=n;i++)
{
f[i]=max(f[i],ask(s[i])+1);
add(s[i]+1,f[i]);
}
for(int i=1;i<=n;i++)
ans=max(f[i],ans);
printf("%lld",ans);
if(!task) return 0;
cnt++;
insert(root,1,cnt,s[1]+1,1,1);
for(int i=2;i<=n;i++)
{
pair<int,int> temp=query(root,1,cnt,1,s[i]);
siz[i]=max(1ll,temp.second%mod);
insert(root,1,cnt,s[i]+1,f[i],siz[i]);
}
for(int i=1;i<=n;i++)
if(f[i]==ans)
answer=(answer+siz[i])%mod;
printf("\n%lld",answer);
return 0;
}
T3 幻魔皇
解题思路
不难发现所有的都是和斐波那契有关的(比如每一层的黑色或者白色节点的数量)。
先抛开最顶部的白色节点,考虑下面所有节点的贡献,最后单独处理就好了。
考虑分别计算以黑色节点和以白色节点为根的子树的贡献。
对于白色节点为根节点的比较简单,直接循环子树里每一层的就好了。
黑色节点子树中的白色节点分为两种情况:
直接与黑色子树根节点相连的。
其它的
对于第二种情况直接斐波那契数列推就好了,分别枚举左子树的深度和右子树的深度就好了。
第一种情况也类似于上面,只枚举另一侧子树的深度计算就好了。
这样就是 80pts 做法,100pts 只要把前两维初始化一下就好了。
code
80pts
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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=1e4+10,mod=123456789;
int n,f[N],ans[N];
signed main()
{
n=read();
f[1]=f[2]=1;
for(int i=3;i<=n;i++)
f[i]=(f[i-1]+f[i-2])%mod;
for(int i=2;i<=n;i++)
{
for(int j=i+2;j<=n;j++)
{
for(int k=i+3;k<=n;k++)
ans[j-i+k-i]=(ans[j-i+k-i]+f[i-1]*f[j-i-1]%mod*f[k-i-2]%mod)%mod;
ans[j-i+1]=(ans[j-i+1]+f[i-1]*f[j-i-1]%mod)%mod;
}
for(int j=i+1;j<n;j++)
ans[j-i+1]=(ans[j-i+1]+f[i-2]*f[j-i]%mod)%mod;
}
for(int i=3;i<=n;i++)
ans[i-1]=(ans[i-1]+f[i-2])%mod;
for(int i=1;i<=2*n;i++)
printf("%lld ",ans[i]);
return 0;
}
正解
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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=1e4+10,mod=123456789;
int n,f[N],ans[N],q[N][N];
signed main()
{
n=read();
f[1]=f[2]=1;
for(int i=3;i<=n;i++)
f[i]=(f[i-1]+f[i-2])%mod;
for(int i=2;i<=n;i++)
{
for(int j=1;j<=2*n;j++)
q[i][j]=(q[i][j]+q[i-1][j])%mod;
for(int j=3;j<=n;j++)
q[max(i,j)][i+j]=(q[max(i,j)][i+j]+f[i-1]*f[j-2]%mod)%mod;
}
for(int i=2;i<=n;i++)
{
for(int j=5;j<=2*(n-i);j++)
ans[j]=(ans[j]+q[n-i][j]*f[i-1]%mod)%mod;
for(int j=i+2;j<=n;j++)
ans[j-i+1]=(ans[j-i+1]+f[i-1]*f[j-i-1]%mod)%mod;
for(int j=i+1;j<n;j++)
ans[j-i+1]=(ans[j-i+1]+f[i-2]*f[j-i]%mod)%mod;
}
for(int i=3;i<=n;i++)
ans[i-1]=(ans[i-1]+f[i-2])%mod;
for(int i=1;i<=2*n;i++)
printf("%lld ",ans[i]);
return 0;
}
7.28考试总结(NOIP模拟26)[神炎皇·降雷皇·幻魔皇]的更多相关文章
- 2021.7.28考试总结[NOIP模拟26]
罕见的又改完了. T1 神炎皇 吸取昨天三个出规律的教训,开场打完T2 20pts直接大力打表1h. 但怎么说呢,我不懂欧拉函数.(其实exgcd都忘了 于是只看出最大平方因子,不得不线性筛,爆拿60 ...
- [考试总结]noip模拟26
首先看到这样中二的题目心头一震.... 然而发现又是没有部分分数的一天. 然而正解不会打.... 那还是得要打暴力. 但是这套题目有两个题目只有一个参数. 所以... (滑稽).jpg 然后我就成功用 ...
- 2021.9.28考试总结[NOIP模拟64]
T1 三元组 发现确定\(b,c\)的情况下,\(a\)的值域是连续的.确定\(b\)后\(a+b\)的取值是\([1+b,b+b]\).树状数组维护对每个\(b\)可行的\(c\). 注意取模后取值 ...
- noip模拟26[肾炎黄·酱累黄·换莫黄]
\(noip模拟26\;solutions\) 这个题我做的确实是得心应手,为啥呢,因为前两次考试太难了 T1非常的简单,只不过我忘记了一个定理, T2就是一个小小的线段树,虽然吧我曾经说过我再也不写 ...
- 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]
6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...
- 5.23考试总结(NOIP模拟2)
5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...
- 5.22考试总结(NOIP模拟1)
5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...
- NOIP模拟26「神炎皇·降雷皇·幻魔皇」
T1:神炎皇 又是数学题,气死,根本不会. 首先考虑式子\(a+b=ab\),我们取\(a\)与\(b\)的\(gcd\):\(d\),那么式子就可以改写成: \[(a'+b')*d=a'b' ...
- 2021.9.17考试总结[NOIP模拟55]
有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...
- [考试总结]noip模拟23
因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...
随机推荐
- python 代码编写环境及编辑器配置
前言 关于python 环境编辑器的配置. 正文 第一步:python解释器,到网上下载安装下就行. 网址:https://www.python.org/downloads/windows/ 值得注意 ...
- 使用ollama分别在我的window、mac、小米手机上部署体验llama3-8b
1.ollama到底是个什么玩意 一句话来说, Ollama 是一个基于 Go 语言开发的简单易用的本地大模型运行框架.可以将其类比为 docker(有类似docker中的一些常规命令list,pul ...
- three.js实现数字孪生3D仓库一期(开源)
大家好,本文使用three.js实现了3D仓库一期项目,给出了代码,分析了关键点,感谢大家~ 关键词:数字孪生.three.js.Web3D.WebGL.智慧仓库.开源 代码:Github 我正在承接 ...
- DC-1渗透靶场实战速通版
"感谢您阅读本篇博客!如果您觉得本文对您有所帮助或启发,请不吝点赞和分享给更多的朋友.您的支持是我持续创作的动力,也欢迎留言交流,让我们一起探讨技术,共同成长!谢谢!" 文章为速通 ...
- 3 种发布策略,解决 K8s 中快速交付应用的难题
作者 | 郝树伟(流生)阿里云高级研发工程师 前言 软件技术更新换代很快,但我们追求的目标是一直不变的,那就是在安全稳定的前提下,增加应用的部署频率,缩短产品功能的迭代周期,这样的好处就是企业可以在更 ...
- 迁移 Express 到函数计算
首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算准备计 ...
- 六年团队Leader实战秘诀|程序员最重要的八种软技能
简介:笔者在带团队的六年中发现,程序员们在职场都有一个共同的困扰:"好像写代码都没什么问题了,日常工作基本上都是应付业务需求的开发,好像找不到其他的更大的附加价值了,我应该找一些什么样的发 ...
- KubeDL HostNetwork:加速分布式训练通信效率
简介:ubeDL 为分布式训练作业带来了 HostNetwork 网络模式,支持计算节点之间通过宿主机网络相互通信以提升网络性能,同时适应 RDMA/SCC 等新型高性能数据中心架构的网络环境,此外 ...
- Flink 在顺丰的应用实践
简介: 顺丰基于 Flink 建设实时数仓的思路,引入 Hudi On Flink 加速数仓宽表,以及实时数仓平台化建设的实践. 本⽂由社区志愿者苗文婷整理,内容源⾃顺丰科技大数据平台研发工程师龙逸 ...
- WPF 布局 在有限空间内让两个元素尽可能撑开的例子
我在尝试写一个显示本机 WIFI 热点的账号和密码的控件,要求此控件在有限的空间内显示.但是尽可能显示出热点的账号和密码.而热点的账号和密码是用户配置的,也许长度很长.我的需求是在假如账号的长度较短的 ...