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

前言

疯狂挂分,本来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. Pytorch-tensor的转置,运算

    1.矩阵的转置 方法:t() a=torch.randint(1,10,[2,3]) print(a,'\n') print(a.t()) 输出结果 tensor([[2, 8, 2], [9, 2, ...

  2. 【转】Java程序员常用工具类库 - 目录

    原文地址:http://rensanning.iteye.com/blog/1553076 有人说当你开始学习Java的时候,你就走上了一条不归路,在Java世界里,包罗万象,从J2SE,J2ME,J ...

  3. Flink Standalone集群部署

    Flink Standalone模式部署集群是最简单的一种部署方式,不依赖于其他的组件,另外还支持YARN/Mesos/Docker等模式下的部署,这里使用的flink版本为最新的稳定版1.9.1版本 ...

  4. 力扣442(java)-数组中重复的数据(中等)

    题目: 给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 .请你找出所有出现 两次 的整数,并以数组形式返回. 你必须设 ...

  5. 大数据时代下的App数据隐私安全

    ​简介:随着信息技术快速发展,大数据为我们带来信息共享.便捷生活的同时,还存在着数据安全问题,主流商业模式下APP面临新的挑战.工信部持续开展APP侵权整治活动,进行了了六批次集中抽检,检查了76万款 ...

  6. [GPT] ./ssh/known_hosts 是什么

      ~/.ssh/known_hosts 是一个SSH客户端用来存储已知的远程主机的公钥的文件,这些公钥用于验证连接到远程主机时它们是否为真实可信的主机. 当你首次通过SSH连接到一个新的远程主机时, ...

  7. [FAQ] FinalCutPro 添加转场提示“片段边缘之外没有足够的额外媒体可用来创建转场”

    可以把前镜头素材的结尾和后镜头素材的开始减去一部分即可添加转场了. 怎么剪?时间线中有个播放线,快捷键 i 表示选中开始点,快捷键 o 表示选中结束点,使用 delete 键删除选取的部分即可. &g ...

  8. [FAQ] golang-migrate/migrate error: default addr for network '127.0.0.1:3306' unknown

    按照项目github文档上所示,在使用 mysql 时你可能会这样写: $ migrate -path db/migrations -database mysql://root:123456@127. ...

  9. vue+vant+js实现购物车原理小demo(中级版有选择)

    增加只计算已选的的购物车商品功能.效果图: main.js: Vue.use(Stepper); Vue.use(Checkbox); Vue.use(CheckboxGroup); 上代码: < ...

  10. Python多线程编程深度探索:从入门到实战

    title: Python多线程编程深度探索:从入门到实战 date: 2024/4/28 18:57:17 updated: 2024/4/28 18:57:17 categories: 后端开发 ...