考试总结:这次考试,前两道题的题面描述不是很清楚,导致我不知道输出格式到底是什么,挂了差不多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. 学习Qt Charts - Qt Charts的坐标轴

    这次来学学Qt chart 的坐标轴 有这么一组数据: 这是深圳市2019年6月份的天气预报(来自中国天气网:深圳),里面有每天的最高温度,把这最高温度做成个数组,如下: int daily_temp ...

  2. 精尽Spring Boot源码分析 - Jar 包的启动实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  3. 一文说透 Go 语言 HTTP 标准库

    本篇文章来分析一下 Go 语言 HTTP 标准库是如何实现的. 转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/561 ...

  4. Unity项目代码书写规范

    以Google的代码规范为主,稍加改动 https://google.github.io/styleguide/csharp-style.html 书写规范 基础写法 Pascal和驼峰混用,参数用驼 ...

  5. ABP Framework:移除 EF Core Migrations 项目,统一数据上下文

    原文:Unifying DbContexts for EF Core / Removing the EF Core Migrations Project 目录 导读:软件开发的一切都需要平衡 动机 警 ...

  6. xf浅谈_最短路

    最短路问题(short-path problem):最短路问题是图论研究中的一个经典算法问题,指在寻找图(由结点和路径组成的)中两结点之间的最短路径.算法具体的形式包括: 1.确定起点的最短路径问题 ...

  7. 揭开Docker的面纱

    开新坑了,开始挖坑Docker了,兄弟们.为什么需要Docker呢?Docker是什么?这里开始揭开Docker的面纱. 一.为什么需要Docker 可能每个开发人员都有一种困扰,软件开发完之后部署项 ...

  8. C# 小知识点记录

    1.当计算数据有小数点时不要使用float和double类型的数据,使用这两个会计算不准确.使用decimal 2.如果使用decimal计算数据,遇到除不进的数据有很多小数点的时候,在计算结果后面接 ...

  9. SpringBoot 优雅整合Swagger Api 自动生成文档

    前言 一个好的可持续交付的项目,项目说明,和接口文档是必不可少的,swagger api 就可以帮我们很容易自动生成api 文档,不需要单独额外的去写,无侵入式,方便快捷大大减少前后端的沟通方便查找和 ...

  10. Laravel + Swoole 打造IM简易聊天室

    最近在学习Swoole,利用Swoole扩展让PHP生动了不少,本篇就来Swoole开发一款简易的IM聊天室 应用场景:实现简单的即时消息聊天室. (一)扩展安装 pecl install swool ...