或许只需一滴露水,便能守护这绽放的花朵。

前言

疯狂挂分,本来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 幻魔皇

解题思路

不难发现所有的都是和斐波那契有关的(比如每一层的黑色或者白色节点的数量)。

先抛开最顶部的白色节点,考虑下面所有节点的贡献,最后单独处理就好了。

考虑分别计算以黑色节点和以白色节点为根的子树的贡献。

对于白色节点为根节点的比较简单,直接循环子树里每一层的就好了。

黑色节点子树中的白色节点分为两种情况:

  1. 直接与黑色子树根节点相连的。

  2. 其它的

对于第二种情况直接斐波那契数列推就好了,分别枚举左子树的深度和右子树的深度就好了。

第一种情况也类似于上面,只枚举另一侧子树的深度计算就好了。

这样就是 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)[神炎皇·降雷皇·幻魔皇]的更多相关文章

  1. 2021.7.28考试总结[NOIP模拟26]

    罕见的又改完了. T1 神炎皇 吸取昨天三个出规律的教训,开场打完T2 20pts直接大力打表1h. 但怎么说呢,我不懂欧拉函数.(其实exgcd都忘了 于是只看出最大平方因子,不得不线性筛,爆拿60 ...

  2. [考试总结]noip模拟26

    首先看到这样中二的题目心头一震.... 然而发现又是没有部分分数的一天. 然而正解不会打.... 那还是得要打暴力. 但是这套题目有两个题目只有一个参数. 所以... (滑稽).jpg 然后我就成功用 ...

  3. 2021.9.28考试总结[NOIP模拟64]

    T1 三元组 发现确定\(b,c\)的情况下,\(a\)的值域是连续的.确定\(b\)后\(a+b\)的取值是\([1+b,b+b]\).树状数组维护对每个\(b\)可行的\(c\). 注意取模后取值 ...

  4. noip模拟26[肾炎黄·酱累黄·换莫黄]

    \(noip模拟26\;solutions\) 这个题我做的确实是得心应手,为啥呢,因为前两次考试太难了 T1非常的简单,只不过我忘记了一个定理, T2就是一个小小的线段树,虽然吧我曾经说过我再也不写 ...

  5. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  6. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  7. 5.22考试总结(NOIP模拟1)

    5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...

  8. NOIP模拟26「神炎皇·降雷皇·幻魔皇」

    T1:神炎皇   又是数学题,气死,根本不会.   首先考虑式子\(a+b=ab\),我们取\(a\)与\(b\)的\(gcd\):\(d\),那么式子就可以改写成: \[(a'+b')*d=a'b' ...

  9. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  10. [考试总结]noip模拟23

    因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...

随机推荐

  1. 重新点亮linux 命令树————rpm软件包管理[十一七]

    前言 简单介绍一下软件管理 正文 软件包管理器 rpm 包和rpm 命令 yum 仓库 源代码编译安装 内核升级 grub配置文件 软件包管理器: 包管理器是为了方便软件安装.卸载,解决软件依赖关系的 ...

  2. 旧版本的centOS下载(国内-清华)

    链接如下: https://mirrors.tuna.tsinghua.edu.cn/centos-vault/

  3. 力扣15(Java)-三数之和(中等)

    题目: 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j.i != k 且 j != k ,同时还满足 nums[i] + ...

  4. 蚂蚁一面:GC垃圾回收时,内存分配和回收策略有哪些?

    文章首发于公众号:腐烂的橘子 蚂蚁面试主要为电话面试,期间也会要求使用编辑器手写算法题.作为一线互联网大厂,Java 基础知识是必备的,其中垃圾回收也是面试过程中的重中之重. Java 内存的自动管理 ...

  5. 数据库PolarDB开源之路该如何走?听听他们怎么说

    简介: 10月25日,由阿里云开发者社区.阿里云PolarDB开源社区.InfoQ联合举办的「开源人说」数据库PolarDB专场线下沙龙在杭州召开,5位阿里云数据库超级大咖.10位阿里云数据库开源生态 ...

  6. Java 定时任务技术趋势

    ​简介:定时任务是每个业务常见的需求,比如每分钟扫描超时支付的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报表等等. 作者:黄晓萌(学仁) Java 中自带的解决方案 使用 Time ...

  7. 从 Flink Forward Asia 2021,看Flink未来开启新篇章

    ​简介:本文将对FFA Keynote议题作一些简单的归纳总结,感兴趣的小伙伴们可以在FFA官网[2]找到相关主题视频观看直播回放. ​ 作者 | 梅源(Yuan Mei) 来源 | 阿里技术公众号 ...

  8. github 解决推拉代码提示 REMOTE HOST IDENTIFICATION HAS CHANGED 失败

    本文记录最近 github 推送或拉取代码时提示 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 而失败的解决方法 报错提示如下 @@@@@@@@@@ ...

  9. 高性能消息中间件-Nats使用

    一.Nats简介 官网:https://nats.io/ 官网下载:https://nats.io/download/ github:https://github.com/nats-io/nats-s ...

  10. 第3讲-Cadence分裂元件的制作方法

    笔记3-Cadence分裂元件的制作方法 1.Homogeneous和heterogeneous的区别: 2.创建homogeneous类型元件: 3.创建heterogeneous类型元件. 把元件 ...