7.20考试总结(NOIP模拟21)[Median·Game·Park]
雨滴降落的速度是每秒十米,我该用怎么样的速度,才能将你挽留?
前言
关于语文素养如何限制OI水平2,正好现在文化课巨佬们正在考语文(那我走???)
T1 我以为整数是不用输出 .0 的,然后喜挂 30pts。
T2 差值不应该是绝对值???,然后题解认为不需要取,喜挂 45pts。
T1 Median
解题思路
首先明确一下暴力分(线性筛+暴力排序),有 50pts 之高。
其次明确一下中位数需要排序,然后输出方面上面也说了。。
正解有一点玄学,官方题解是这么说的:
然后注意到这题的输入很诡异,其实可以当做是随机数据
那么随机数据满足分布均匀,也就是说可以假定,中位数值变化也是常数级的。
然后题解就认为可以暴力维护中位数指针了。。。(我***)
对于奇数而言,先暴力排序搞出第一个区间的中位数以及各个数的桶,并且记录一下小于等于中位数的数的数量。
然后在向后查找的时候,不断维护更新中位数以及桶还有数量就好了。
偶数的话,维护两个要取平均值的两个数就好了。
Linux编译的时候终端对于大的数据可能会直接判断为 RE,可以开 O2 或者 Ofast:
g++ t.cpp -Ofast -o t && ./t
然后处理的时候注意一下边界问题,并且不要全部开 long long 就 OK 了。
code
#include<bits/stdc++.h>
//#define int long long
#define re 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,len,mod,num,num1,num2,cnt,pri[N],s[N],s2[N];
int sta[N];
int sum,sum1,sum2,vis[N];
bitset<18*N> jud;
double ans;
void Get_Prime()
{
for(int i=2;cnt<n;i++)
{
if(!jud[i]) pri[++cnt]=i;
for(int j=1;j<=cnt&&pri[j]*i<=18*n;j++){
jud[pri[j]*i]=true;
if(i%pri[j]==0)break;
}
}
}
signed main()
{
n=read();
len=read();
mod=read();
Get_Prime();
for(int i=1;i<=n;i++)
s[i]=1ll*i*pri[i]%mod;
for(int i=1;i<=n;i++)
s2[i]=s[i]+s[i/10+1];
for(int i=1;i<=len;i++)
sta[i]=s2[i],vis[s2[i]]++;
sort(sta+1,sta+len+1);
num=len/2;
if(len&1) ans+=sta[num+1]*1.0;
else ans+=(1.0*sta[num]+1.0*sta[num+1])/2.0;
num=sta[len/2+1];
num1=sta[len/2],num2=sta[len/2+1];
if(len&1)
for(int i=0;i<=num;i++)
sum+=vis[i];
else
{
for(int i=0;i<=num2;i++)
sum1+=vis[i];
for(int i=0;i<=num1;i++)
sum2+=vis[i];
}
for(int l=2;l<=n-len+1;l++)
{
int r=l+len-1;
if(len&1)
{
vis[s2[l-1]]--;
if(s2[l-1]<=num) sum--;
vis[s2[r]]++;
if(s2[r]<=num) sum++;
while(1)
{
if(sum-vis[num]>len/2) sum-=vis[num],num--;
else if(len-sum>len/2) num++,sum+=vis[num];
if(sum-vis[num]<=len/2&&len-sum<=len/2)
break;
}
ans+=num;
}
else
{
vis[s2[l-1]]--;
vis[s2[r]]++;
if(s2[l-1]<=num1) sum1--;
if(s2[r]<=num1) sum1++;
if(s2[l-1]<=num2) sum2--;
if(s2[r]<=num2) sum2++;
while(sum1-vis[num1]>=len/2) sum1-=vis[num1],num1--;
while(sum1+vis[num1+1]<len/2) sum1+=vis[num1+1],num1++;
if(sum1<len/2) num1++,sum1+=vis[num1];
while(sum2-vis[num2]>=len/2+1) sum2-=vis[num2],num2--;
while(sum2+vis[num2+1]<len/2+1) sum2+=vis[num2+1],num2++;
if(sum2<len/2+1) num2++,sum2+=vis[num2];
ans+=(1.0*num1+1.0*num2)/2.0;
}
}
printf("%.1lf",ans);
return 0;
}
T2 Game
解题思路
对于非正解的算法而言,set 或者是优先队列都可以搞到 50pts。
其实并不需要那么麻烦的操作,不难发现,如果要加入的数大于当前区间的最大值的话,那么它就一定会被取走。
因此只需要维护新进入区间的值就可以了。
然后观察到其实值域很小,因此可以开个桶维护。
code
#include<bits/stdc++.h>
#define int 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,m=1e7+10;
int n,opt,now,maxn,ans[2],T,s[N],t[N];
void solve()
{
opt=read();
ans[0]=ans[1]=0;
maxn=now=0;
for(int i=1;i<opt;i++)
{
t[s[i]]++;
maxn=max(maxn,s[i]);
}
for(int i=opt;i<=n;i++)
{
if(s[i]>=maxn) ans[now]+=s[i];
else
{
t[s[i]]++;
t[maxn]--;
ans[now]+=maxn;
while(!t[maxn]) maxn--;
}
now=(!now);
}
for(int i=maxn;i>=1;i--)
while(t[i])
{
ans[now]+=i;
t[i]--;
now=(!now);
}
printf("%lld\n",ans[0]-ans[1]);
}
signed main()
{
n=read();
T=read();
for(int i=1;i<=n;i++)
s[i]=read();
while(T--) solve();
return 0;
}
T3 Park
解题思路
出题人对于[CEOI2017]Chase 的题面魔改了一下就扔给了我们。
树形 DP,开两个数组 f[i][j]和 g[i][j] 分别记录从 i 到 i 的子树以及从 i 的子树到 i 撒了 j 个的最大贡献。
然后尝试着把在一棵子树中经过子树根节点一条路径(假设是根节点为 rt 从 \(u\rightarrow v\))拆成两部分:
\(u\rightarrow rt\rightarrow v\) 这样就可以用 f 和 g 数组进行转移了。
然后预处理出每个节点周围节点的值的和,在运算的时候减去已经经过的。
最后要注意,对于每一棵子树要正反进行两边,要保证每一种解都可以扫到,毕竟路径的正反是不同的。
code
#include<bits/stdc++.h>
#define int 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;
int n,m,ans,s[N],cnt[N],f[N][110],g[N][110];
int tot,head[N],nxt[N<<1],ver[N<<1];
void add_edge(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void dfs(int x,int fa)
{
vector<int> v;
vector<int>().swap(v);
for(int i=1;i<=m;i++)
{
f[x][i]=cnt[x];
g[x][i]=cnt[x]-s[fa];
}
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
if(to==fa) continue;
v.push_back(to);
dfs(to,x);
for(int j=0;j<=m;j++)
ans=max(ans,f[x][j]+g[to][m-j]);
for(int j=1;j<=m;j++)
{
f[x][j]=max(f[x][j],max(f[to][j],f[to][j-1]+cnt[x]-s[to]));
g[x][j]=max(g[x][j],max(g[to][j],g[to][j-1]+cnt[x]-s[fa]));
}
}
for(int i=1;i<=m;i++)
{
f[x][i]=cnt[x];
g[x][i]=cnt[x]-s[fa];
}
if(!v.size()) return ;
for(int i=v.size()-1;i>=0;i--)
{
int to=v[i];
for(int j=0;j<=m;j++)
ans=max(ans,f[x][j]+g[to][m-j]);
for(int j=1;j<=m;j++)
{
f[x][j]=max(f[x][j],max(f[to][j],f[to][j-1]+cnt[x]-s[to]));
g[x][j]=max(g[x][j],max(g[to][j],g[to][j-1]+cnt[x]-s[fa]));
}
}
}
signed main()
{
n=read();
m=read();
for(int i=1;i<=n;i++)
s[i]=read();
for(int i=1,x,y;i<n;i++)
{
x=read();
y=read();
add_edge(x,y);
add_edge(y,x);
cnt[x]+=s[y];
cnt[y]+=s[x];
}
dfs(1,0);
printf("%lld",ans);
return 0;
}
7.20考试总结(NOIP模拟21)[Median·Game·Park]的更多相关文章
- [考试总结]noip模拟21
中位数要排序!!!!!! 中位数要排序!!!!!! 中位数要排序!!!!!! 中位数要排序!!!!!! 中位数要排序!!!!!! 分差不加绝对值!!!! 分差不加绝对值!!!! 分差不加绝对值!!!! ...
- 2021.9.20考试总结[NOIP模拟57]
(换个编辑器代码就SB地不自动折叠了.. T1 2A 考察快读的写法. $code:$ T1 #include<bits/stdc++.h> #define scanf SCANF=sca ...
- 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 ...
- 2021.7.21考试总结[NOIP模拟22]
终于碾压小熠了乐死了 T1 d 小贪心一波直接出正解,没啥好说的(bushi 好像可以主席树暴力找,但我怎么可能会呢?好像可以堆优化简单找,但我怎么可能想得到呢? 那怎么办?昨天两道单调指针加桶,我直 ...
- 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\) 的总结写了吧.. 俗话说:" ...
- NOIP模拟21+22
模拟21确实毒瘤...考场上硬刚T3 2.5h,成功爆零 T1.数论 看这题目就让人不想做,考场上我比较明智的打完暴力就弃掉了,没有打很久的表然后找规律. 正解貌似是乱搞,我们考虑一个比较显然的结论: ...
- 2019.6.20 校内测试 NOIP模拟 Day 1 分析+题解
这次是zay神仙给我们出的NOIP模拟题,不得不说好难啊QwQ,又倒数了~ T1 大美江湖 这个题是一个简单的模拟题. ----zay 唯一的坑点就是打怪的时候计算向上取整时,如果用ceil函数一 ...
随机推荐
- docker 应用篇————docker基本命令[四]
前言 介绍一下一些docker的基本命令. 正文 帮助命令: 首先要学的肯定是docker --help 命令了,因为这样我们就不用经常去查官网. docker version docker info ...
- js es6 delete
前言 首先delete 不同于nodejs delete,看下有什么不同. 正文 var test=5; delete test; console.log(test); 结果是test没有受到任何影响 ...
- C3P0反序列化链分析
前言 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.使用它的开源项目有Hibernate.Spring等.之前有接触到过,但是没有深入了解 ...
- 开篇:Mirth Connect系统集成与数据交换引擎
Mirth最初的目的是作为HL7接口引擎('引擎'释意:IT方面的术语,指经包装过的函数库,方便别人调用:如搜索引擎.图形引擎.物理引擎等),HL7 v2.x和HL7 v3标准通常在医疗系统间用于系统 ...
- 力扣566(java)-重塑矩阵(简单)
题目: 在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据. 给你一个由二维数组 mat 表示的 ...
- 跨模态学习能力再升级,EasyNLP电商文图检索效果刷新SOTA
简介: 本⽂简要介绍我们在电商下对CLIP模型的优化,以及上述模型在公开数据集上的评测结果.最后,我们介绍如何在EasyNLP框架中调用上述电商CLIP模型. 作者:熊兮.欢夏.章捷.临在 导读 多模 ...
- 持续定义Saas模式云数据仓库+实时分析
简介: 从实时分析的价值.场景和数据流程,以及用户对平台能力要求展开,讲述云数据仓库MaxCompute的产品能力优势 ,面对实时分析场景的能力演进要求.进而以实时分析典型场景的全数据流程处理.建模和 ...
- WPF 使用 Win10 的 WinRT 自带 Windows.Media.Ocr 实现图片转文本
世界上有很多 OCR 识别技术,本文来和大家介绍如果在 WPF 里,在运行到 win10 的设备上,通过 Windows Runtime 自带的 Windows.Media.Ocr 实现在给定的图片里 ...
- dotnet 开启 Fiddler 抓包将会让请求 HOST 头被更改
我在写域名备份功能,想要修改请求的 IP 地址,同时又将原有的请求域名带上.实现方法是修改请求的地址,在 HttpRequestMessage 的 Header 上添加 HOST 记录,记录的值就是原 ...
- C# - 能否让 SortedSet.RemoveWhere 内传入的委托异步执行
TL;DR; 若想充分利用 RemoveWhere 带来的性能优势,建议传入判断是否删除元素的委托内采取同步操作.若一定要在该委托内使用异步操作,可以采用本文中绕行的方法,但摈弃了 RemoveWhe ...