考试总结:这次考试,前两道题的题面描述不是很清楚,导致我不知道输出格式到底是什么,挂了差不多80分(好多人也是这样),总体来说,这次考试的前两道题暴力分是打满了,最后一道题打了一个假的暴搜,在考场上没调出来,代码能力还需提高。

T1 Median

思路:我们首先利用线性筛求出我们需要的素数,然后求出整个序列,接下来我们考虑计算中位数,首先明确一个问题,这中位数是将区间里的数从大到小排好序之后的中间的那个数,(我当时因为这个调了老半天),之后我们注意到这个区间长度是一个定值,每次移动只会有两个值出现的次数发生变化,那我们就可以利用一个桶,记录每个数出现的次数,然后维护一个指针指向中位数的位置,当我们移动的时候,相应的更新指针的位置,具体实现见代码:

AC_Code

#include<bits/stdc++.h>
#define re register int
#define ii inline int
#define iv inline void
using namespace std;
const int M=2e7+10;
const int G=1e7+10;
const int P=1e8+8e7;
double ans;
int n,k,w,sum,ls;
int s1[M],s2[M],pr[G],u[G],tong[M];
bool ifs[P];
ii read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=0;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return (f)?x:(-x);
}
iv get_prime()
{
for(re i=2;sum<=G;i++)
{
if(!ifs[i])
{
pr[++sum]=i;
}
for(re j=1;j<=sum&&i*pr[j]<=P;j++)
{
ifs[i*pr[j]]=1;
if(i%pr[j]==0)
break;
}
}
for(re i=1;i<=n;i++)
s1[i]=1ll*pr[i]%w*i%w;
for(re i=1;i<=n;i++)
s2[i]=1ll*s1[i]+s1[i/10+1];
}
int my(int a,int b)
{
return a<b;
}
iv solve1()
{
long long mid;
for(re i=1;i<=k;i++)
{
u[i]=s2[i];
tong[s2[i]]++;
}
sort(u+1,u+k+1,my);
mid=u[(k+1)/2];
ls=upper_bound(u+1,u+k+1,mid)-u-1;
ans+=mid;
for(re i=2;i<=n-k+1;i++)
{
tong[s2[i-1]]--;
tong[s2[i+k-1]]++;
if(s2[i-1]*1ll<=mid)
ls--;
if(s2[i+k-1]*1ll<=mid)
ls++;
while(1)
{
if(1ll*(ls-tong[mid])>=((k+1)/2))
{
ls-=tong[mid];
mid--;
}
else if(1ll*(k-ls)>=((k+1)/2))
{
mid++;
ls+=tong[mid];
}
if((ls-tong[mid]<((k+1)/2))&&(k-ls<((k+1)/2)))
break;
}
ans+=mid;
}
printf("%.1lf\n",(double)ans);
}
iv solve2()
{
double mid;
long long l1,l2,m1,m2;
for(re i=1;i<=k;i++)
{
u[i]=s2[i];
tong[s2[i]]++;
}
sort(u+1,u+k+1,my);
mid=((double)u[k/2]+(double)u[k/2+1])/(double)2;
l1=upper_bound(u+1,u+k+1,u[k/2])-u-1;
l2=upper_bound(u+1,u+k+1,u[k/2+1])-u-1;
m1=u[k/2];
m2=u[k/2+1];
ans+=mid;
for(re i=2;i<=n-k+1;i++)
{
tong[s2[i-1]]--;
tong[s2[i+k-1]]++;
if(s2[i-1]<=m1)
{
l1--;
}
if(s2[i-1]<=m2)
{
l2--;
}
if(s2[i+k-1]<=m1)
{
l1++;
}
if(s2[i+k-1]<=m2)
{
l2++;
}
while(l1-tong[m1]>=(k/2))
{
l1-=tong[m1];
--m1;
}
while(l1+tong[m1+1]<(k/2))
{
++m1;
l1+=tong[m1];
}
if(l1<(k/2))
{
++m1;
l1+=tong[m1];
}
while(l2-tong[m2]>=(k/2+1))
{
l2-=tong[m2];
m2--;
}
while(l2+tong[m2+1]<(k/2+1))
{
++m2;
l2+=tong[m2];
}
if(l2<(k/2+1))
{
++m2;
l2+=tong[m2];
}
ans+=((double)m1+(double)m2)/(double)2;
}
long long out=ans;
if((ans-(double)out)==0.5)
printf("%.1lf\n",(double)out+0.5);
else
printf("%.1lf\n",(double)out); }
signed main()
{
n=read();
k=read();
w=read();
get_prime();
if(k&1)
solve1();
else
solve2();
/*long long out=ans;
if((ans-(double)out)==0.5)
printf("%.1lf\n",(double)out+0.5);
else
printf("%.1lf\n",(double)out);*/ return 0;
}


T2 Game

思路:因为根据最优策略,如果我要放进去的球比当前序列的最大值还要大,那么我直接就把它拿走了,就不把它放入序列了,所以,如果我们维护一个指向当前序列最大值的指针,那么这个指针显然是单调递减的,我们每次操作后维护这个指针即可,具体实现见代码:

AC_Code

#include<bits/stdc++.h>
#define re register int
#define lc rt<<1
#define rc rt<<1|1
#define mid ((l+r)>>1)
#define re register int
#define ii inline int
#define iv inline void
using namespace std;
const int N=1e5+10;
int n,k,p,cnt,num,mx,use;
int a[N],b[N];
long long tong[N];
long long A,B,la,lb;
ii read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=0;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return (f)?x:(-x);
}
iv change()
{
if(!tong[mx])
{
while(1)
{
mx--;
if(tong[mx]||(mx<=0))
break;
}
}
}
int main()
{
n=read();
k=read();
for(re i=1;i<=n;i++)
a[i]=read();
for(re i=1;i<=k;i++)
{
p=read();
A=0;
B=0;
la=-1;
lb=-1;
cnt=0;
mx=-1;
use=0;
bool pd;
memset(tong,0,sizeof(tong));
for(re j=1;j<=n;j++)
{
while(j<=p&&j<=n)
{
tong[a[j]]++;
mx=max(mx,a[j]);
j++;
}
pd=0;
cnt=j-1;
while(1)
{
if(pd==0||cnt>=n)
{
change();
A+=mx;
tong[mx]--;
change();
}
else if(cnt<n)
{
++cnt;
if(a[cnt]>=mx)
{
A+=a[cnt];
}
else if(tong[mx])
{
A+=mx;
tong[a[cnt]]++;
tong[mx]--;
change();
}
else
{
tong[a[cnt]]++;
change();
A+=mx;
tong[mx]--;
change();
}
}
++use;
if(use==n)
break;
if(cnt<n)
{
++cnt;
if(a[cnt]>=mx)
{
B+=a[cnt];
}
else if(tong[mx])
{
B+=mx;
tong[a[cnt]]++;
tong[mx]--;
change();
}
else
{
tong[a[cnt]]++;
change();
B+=mx;
change();
}
}
else
{
change();
B+=mx;
tong[mx]--;
change();
}
++use;
if(use==n)
break;
if(la==A&&lb==B)
break;
la=A;
lb=B;
pd=1;
}
break;
}
printf("%lld\n",A-B);
}
return 0;
}


T3 Park

一道DP好题,思路:设\(dp_{0,i,j}\)表示我从 i 的子树走到i,一共撒了 j 次的最大差值,设 \(dp_{1,i,j}\)表示从 i的father走向 i ,一共撒了 j 次的最大差值,那么状态转移方程可得 \(dp_{0,i,j}=max(dp_{0,i,j},max(dp_{0,son,j},dp_{0,son,j-1}+sum_i-p_{son}))\) ,\(dp_{1,i,j}=max(dp_{1,i,j},max(dp_{1,son,j},dp_{1,son,j-1}+sum_i-p_{father}))\)

但是,因为我们自上而下和自下而上计算可能会得到不一样的结果,所以我们还要反着做一遍DP

代码如下:

AC_Code



#include<bits/stdc++.h>
#define re register int
#define ii inline int
#define iv inline void
using namespace std;
const int N=1e5+10;
int n,v;
long long ans;
long long p[N],dp[2][N][110],sum[N];
vector<int> edge[N];
ii read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=0;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return (f)?x:(-x);
}
iv dfs(int x,int f)
{
for(re i=1;i<=v;i++)
{
dp[0][x][i]=sum[x];
dp[1][x][i]=sum[x]-p[f];
}
for(re i=0;i<edge[x].size();i++)
{
if(edge[x][i]==f)
continue;
dfs(edge[x][i],x);
for(re j=1;j<v;j++)
ans=max(ans,dp[0][x][j]+dp[1][edge[x][i]][v-j]);
for(re j=1;j<=v;j++)
{
dp[0][x][j]=max(dp[0][x][j],max(dp[0][edge[x][i]][j],dp[0][edge[x][i]][j-1]+sum[x]-p[edge[x][i]]));
dp[1][x][j]=max(dp[1][x][j],max(dp[1][edge[x][i]][j],dp[1][edge[x][i]][j-1]+sum[x]-p[f]));
}
} reverse(edge[x].begin(),edge[x].end());
for(re i=1;i<=v;i++)
{
dp[0][x][i]=sum[x];
dp[1][x][i]=sum[x]-p[f];
}
for(re i=0;i<edge[x].size();i++)
{
if(edge[x][i]==f)
continue;
for(re j=1;j<v;j++)
ans=max(ans,dp[0][x][j]+dp[1][edge[x][i]][v-j]);
for(re j=1;j<=v;j++)
{
dp[0][x][j]=max(dp[0][x][j],max(dp[0][edge[x][i]][j],dp[0][edge[x][i]][j-1]+sum[x]-p[edge[x][i]]));
dp[1][x][j]=max(dp[1][x][j],max(dp[1][edge[x][i]][j],dp[1][edge[x][i]][j-1]+sum[x]-p[f]));
}
}
for(re i=1;i<=v;i++)
ans=max(ans,max(dp[0][x][i],dp[1][x][i]));
}
signed main()
{
n=read();
v=read();
for(re i=1;i<=n;i++)
scanf("%lld",&p[i]);
int a,b;
for(re i=1;i<n;i++)
{
a=read();
b=read();
edge[a].push_back(b);
edge[b].push_back(a);
sum[a]+=p[b];
sum[b]+=p[a];
}
dfs(1,0);
printf("%lld\n",ans);
return 0;
}


noip模拟测试21的更多相关文章

  1. 2019.8.14 NOIP模拟测试21 反思总结

    模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...

  2. NOIP模拟测试21「折纸&#183;不等式」

    折纸 题解 考试时无限接近正解,然而最终也只是接近而已了 考虑模拟会爆炸,拿手折纸条试一试,很简单 考你动手能力 代码 #include<bits/stdc++.h> using name ...

  3. 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)

    2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

  4. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  5. 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组

    2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...

  6. 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色

    2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...

  7. NOIP模拟测试19「count·dinner·chess」

    反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...

  8. NOIP模拟测试17&18

    NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...

  9. NOIP模拟测试1(2017081501)

    好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...

随机推荐

  1. WEB 三维引擎在高精地图数据生产的探索和实践

    1. 前言 高精地图(High Definition Map)作为自动驾驶安全性不可或缺的一部分,能有效强化自动驾驶的感知能力和决策能力,提升自动驾驶的等级.对于自动驾驶来说,高精地图主要是给机器用的 ...

  2. 冷饭新炒 | 深入Quartz核心运行机制

    目录 Quartz的核心组件 JobDetail Trigger 为什么JobDetail和Trigger是一对多的关系 常见的Tigger类型 怎么排除掉一些日期不触发 Scheduler List ...

  3. 在微信小程序中使用阿里图标库Iconfont

    首先想要使用图标,只用上图的五个iconfont相关文件就可以了.(下下来的文件iconfont.wxss开始是.css的后缀,手动改成.wxss就可以在小程序中使用) 然后在app.wxss中引入i ...

  4. 高性能的Redis数据结构小结

    一.概述 Redis 作为一种 KV 缓存服务器,有着极高的性能,相对于 Memcache,Redis 支持更多种数据类型,因此在业界应用广泛. 记得刚毕业那会参加面试,面试官会问我 Redis 为什 ...

  5. vim安装及个性化配置

    1.安装vim,并且vim命令的别名设置为vi yum install vim -y (如果不能识别vim命令,需要先安装vim) vi /etc/bashrc 或者 vi ~/.bashrc 在最后 ...

  6. Vue 消除Token过期时刷新页面的重复提示

    1.问题现象   页面长时间未操作,再刷新页面时,第一次弹出"token失效,请重新登录!"提示,然后跳转到登录页面,接下来又弹出了n个"Token已过期"的后 ...

  7. Hadoop:什么是Hadoop??

    官方讲解: Apache Hadoop 为可靠的,可扩展的分布式计算开发开源软件.Apache Hadoop软件库是一个框架,它允许使用简单的编程模型跨计算机群集分布式处理大型数据集(海量的数据). ...

  8. create-react-app 入门学习

    全局安装 create-react-app npm install create-react-app -g 创建项目 在全局安装了create-react-app 后 创建项目,如果按照下面的第一种办 ...

  9. 一次性讲清楚spring中bean的生命周期之三:bean是如何实例化的

    在前面的两篇博文<一次性讲清楚spring中bean的生命周期之一:getSingleton方法>和<一次性讲清楚spring中bean的生命周期之二:FactoryBean的前世今 ...

  10. JMeter之BeanShell常用内置对象

    一.什么是Bean Shell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法; BeanShell是一种松散类型的脚本语言(这点和JS类似); BeanS ...