Noip2016 总结&反思
一直在期盼的联赛,真正来临时,却远不像我想象的样子。
有些事,真的不敢再想。
算法可以离线,时光却不能倒流。dfs可以回溯,现实却没有如果。
有些事,注定只能成为缺憾,抱恨终生。
不得不说今年Noip画风大变。
一是题目难度不循常规。D1难度如此之大,估计很多人都会很紧张。(比如我,下了场以为要有一群250+的,感觉自己要AFO了。)并且,D1T2居然比D1T3还难(D2也是如此),把好多人给坑了(估计很多人都是死磕T2不放结果T3的76分暴力都没时间写了)。
PS:感觉题目难度应该是这样的,D1T1<D2T1<D1T3<D2T3<D2T2<D1T2
二是题目类型有所变化。今年的题基本没看见模板题,都是一些比较考察思维的题。
“综合来看,相比去年的题目偏重考察知识点,今年的题目在思维难度上有了明显的提升,可以有效的避免“东西学得多,分就高”的情况。在我看来,NOIP 虽然是一个普及形式的比赛,涉及知识点也有限,但并不意味着东西学得多就能 AK,竞赛竞赛,竞的是思维,赛的是心态,而不是仅仅拘泥于学习知识点的多少、学习时间的长短。让所有人都有收获,这可能是我心中比赛应有的样子吧。”——Sengxian
D1T2成功把自己坑了,考场上思路飘逸到树剖树分治和主席树,连一道树上差分都想不出来,都是因为思维能力太垃圾。还有D2T2(是怪我没学过Huffman树不知道用队列做的方法么……)。
联赛比的确实是思维和心态。
自己心态也比较差,考场上没能想出D1T2(放到平常考试估计想个1h也能想出来……),暴力还写挂了,分数-=15;D1T3本来想到正解了,然而脑残的以为最后一维要开3,死活过不去(真是SB,我为什么不试试开2会怎样);D2T1都能飘逸到Lucas定理,真是醉了;一直在叮嘱自己注意卡常,结果D2T2的make_heap()众给我贡献了2T,分数-=10;D2T3一眼看上去居然看成了搜索,明明不会剪枝还硬剪了半个小时,真是废了(放到平常考试估计很快就能看出状压的……)。
至于思维,向来是我的弱项。以前总是在学一些高端的东西,平衡树、主席树、树套树、CDQ……然而这些东西联赛都没能用上(平时最实用的主席树到了这儿也没能用上……),反而学了这些东西之后做了好多模板题,对思维的锻炼就很少了。
联赛的6道题,D1T1和D2T1两道水题水过去了,D2T3一道状压傻逼题卡过去了,D1T2的树上差分、D1T3的期望DP和D2T2的队列都没想出来,写的暴力。
一场考试,6道题,我居然写了3个暴力,真是废了。幸亏暴力分给的足,要不然我早就AFO了。
现在离省选也没多少天了。唯一期盼的就是黑暗的高考生活赶快结束,WC和省选集训早日到来。
言归正传。
D1T1 玩具谜题
水题不解释。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
int n,m,a[maxn],x,d,cur=;
char s[maxn][];
int main(){
scanf("%d%d",&n,&m);
scanf("%d%s",&a[],s[]);
for(int i=n-;i;i--)scanf("%d%s",&a[i],s[i]);
while(m--){
scanf("%d%d",&x,&d);
if(x==a[cur])cur=(cur+d)%n;
else cur=(cur-d+n)%n;
}
printf(s[cur]);
return ;
}
D1T2 天天爱跑步
感觉这种题就该放在D2T3……
首先把每条路径(u,v)拆成两条路径(u,LCA)和(LCA,v)后分别考虑,然后对于每个x,考虑哪些点会对ans[x]产生贡献。
设每个点的深度为d,显然只有满足以下条件的u和v会对x的答案产生贡献:
(对u来说)d[u]-d[x]=w[x]
(对v来说)d[u]-d[LCA]+d[x]-d[LCA]=w[x]
把式子变形,得
d[u]=w[x]+d[x]
d[u]-2*d[LCA]=w[x]-d[x]
这样左边的值就不随x而改变,因为只有单点修改单点查询,用两个数组分别维护即可。
显然对于一个点x,只有(u,v)有一个在x的子树中的路径才能对ans[x]产生贡献。因此我们可以用树上差分,每个修改在u和v处进行,在LCA处撤销,在dfs到一个点之前记录答案,与dfs结束后的答案相减即为子树中的贡献之和。
可能是我写的比较渣,如果对LCA处有贡献的话会算重一次,需要手动去重。
LCA我写的是树剖,后来重写一遍Tarjan结果写挂了,算了反正树剖也挺快我就这么着吧……
细节问题:
a[]维护u的贡献,b[]维护v的贡献。
因为所有u的贡献都一样,直接压缩到cntu[]中表示这个点作为u的次数即可。
u[]是对LCA记录所有u(因为v的贡献只与u有关,所以不用记录v到底是谁),v[]是对v记录所有u和LCA。
因为d[u]-2*d[LCA]可能是负的,因此加上一个2*n的偏移量。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=;
void dfs1(int);
void dfs2(int);
int LCA(int,int);
void dfs(int);
int prt[maxn],size[maxn],d[maxn],son[maxn],top[maxn];
vector<int>G[maxn],u[maxn];
struct pir{int u,lca;pir(int u,int lca):u(u),lca(lca){}};
vector<pir>v[maxn];
int n,m,w[maxn],cntu[maxn]={},ans[maxn]={},x,y;
int a[maxn]={},b[maxn<<]={};
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
dfs1();dfs2();
for(int i=;i<=n;i++)scanf("%d",&w[i]);
while(m--){
scanf("%d%d",&x,&y);
int lca=LCA(x,y);
cntu[x]++;
u[lca].push_back(x);
v[y].push_back(pir(x,lca));
if(d[lca]+w[lca]==d[x])ans[lca]--;
}
dfs();
for(int i=;i<=n;i++)printf("%d ",ans[i]);
return ;
}
void dfs1(int x){
size[x]=;
for(int i=;i<(int)G[x].size();i++)if(G[x][i]!=prt[x]){
prt[G[x][i]]=x;
d[G[x][i]]=d[x]+;
dfs1(G[x][i]);
size[x]+=size[G[x][i]];
if(size[G[x][i]]>size[son[x]])son[x]=G[x][i];
}
}
void dfs2(int x){
if(x==son[prt[x]])top[x]=top[prt[x]];
else top[x]=x;
for(int i=;i<(int)G[x].size();i++)if(G[x][i]!=prt[x])dfs2(G[x][i]);
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
x=prt[top[x]];
}
return d[x]<d[y]?x:y;
}
void dfs(int x){
ans[x]-=a[d[x]+w[x]]+b[w[x]-d[x]+(n<<)];
a[d[x]]+=cntu[x];
for(int i=;i<(int)v[x].size();i++)b[d[v[x][i].u]-(d[v[x][i].lca]<<)+(n<<)]++;
for(int i=;i<(int)G[x].size();i++)if(G[x][i]!=prt[x])dfs(G[x][i]);
ans[x]+=a[d[x]+w[x]]+b[w[x]-d[x]+(n<<)];
for(int i=;i<(int)u[x].size();i++){
a[d[u[x][i]]]--;
b[d[u[x][i]]-(d[x]<<)+(n<<)]--;
}
}
反思:
这题在考场上把我坑了0.5+h,当时什么都想,偏偏想不出来正解……加之前一天晚上睡得很不踏实,有点困,最终还是没想出来,打的60分暴力。结果有15分写挂了,真是废了……
反映出自己思维能力过弱,碰到稍微有点难度的题就想不出来。
一定要少刷模板题。
D1T3 换教室
期望DP模板题,我特么居然跪了……
设f[i][j][0/1]表示前i节课选了j节,0/1表示这节课选了没有的期望值。手玩各种转移就行了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,maxv=;
int n,m,v,e,c[maxn],d[maxn],dis[maxn][maxn],x,y,z;
double p[maxn],f[maxn][maxn][],ans=1e50;
int main(){
memset(dis,,sizeof(dis));
scanf("%d%d%d%d",&n,&m,&v,&e);
m=min(n,m);
for(int i=;i<=v;i++)dis[i][i]=;
for(int i=;i<=n;i++)scanf("%d",&c[i]);
for(int i=;i<=n;i++)scanf("%d",&d[i]);
for(int i=;i<=n;i++)scanf("%lf",&p[i]);
while(e--){
scanf("%d%d%d",&x,&y,&z);
if(z<dis[x][y])dis[x][y]=dis[y][x]=z;
}
for(int k=;k<=v;k++)for(int i=;i<=v;i++)for(int j=;j<=v;j++)dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for(int i=;i<=n;i++)for(int j=;j<=m;j++)f[i][j][]=f[i][j][]=1e50;
f[][][]=f[][][]=0.0;
for(int i=;i<=n;i++)for(int j=;j<=i&&j<=m;j++){
f[i][j][]=min(f[i-][j][]+(double)dis[c[i-]][c[i]],f[i-][j][]+p[i-]*dis[d[i-]][c[i]]+(1.0-p[i-])*dis[c[i-]][c[i]]);
if(j>)f[i][j][]=min(f[i-][j-][]+p[i]*dis[c[i-]][d[i]]+(1.0-p[i])*dis[c[i-]][c[i]],f[i-][j-][]+p[i-]*p[i]*dis[d[i-]][d[i]]+(1.0-p[i-])*p[i]*dis[c[i-]][d[i]]+p[i-]*(1.0-p[i])*dis[d[i-]][c[i]]+(1.0-p[i-])*(1.0-p[i])*dis[c[i-]][c[i]]);
else f[i][j][]=1e50;
}
for(int j=;j<=m;j++)ans=min(ans,min(f[n][j][],f[n][j][]));
printf("%.2lf",ans);
return ;
}
反思:
考场上想到了0/1,然后我脑残的以为应该分没选、选了成功和选了失败三种情况讨论,结果死调不出来,还是写的m<=2的76分暴力,这次倒是没写挂……
第一次好好写期望DP,被干穿了……自己弱不能怪社会……
D2T1 组合数问题
杨辉三角+二维前缀和随便水。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
int q,n,m,p,c[maxn][maxn]={{}},a[maxn][maxn]={{}};
int main(){
scanf("%d%d",&q,&p);
c[][]=;
for(int i=;i<=;i++){
c[i][]=;
for(int j=;j<=i;j++){
c[i][j]=(c[i-][j]+c[i-][j-])%p;
if(!c[i][j])a[i][j]=;
}
}
for(int i=;i<=;i++){
a[i][]+=a[i-][];
a[][i]+=a[][i-];
for(int j=;j<=;j++)a[i][j]+=a[i-][j]+a[i][j-]-a[i-][j-];
}
while(q--){
scanf("%d%d",&n,&m);
printf("%d\n",a[n][m]);
}
return ;
}
反思:
考场上思路有点飘逸,结果费了10min……虽然费的时间不算多吧……
D2T2 蚯蚓
首先把所有蚯蚓变长改成切出来的蚯蚓变短,然后用三个队列分别维护原来的蚯蚓、砍出来的长的那段和短的那段,显然三个队列都是单调的,这样就可以线性了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<functional>
#include<queue>
#define frt(que) ((que.empty()?-2147483647:que.front()))
using namespace std;
int n,m,t,u,v,q,o[],x,a,b,c;
queue<int>qa,qb,qc;
int main(){
scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
for(int i=;i<=n;i++)scanf("%d",&o[i]);
sort(o+,o+n+,greater<int>());
for(int i=;i<=n;i++)qa.push(o[i]);
for(int i=;i<=m;i++){
a=frt(qa);
b=frt(qb);
c=frt(qc);
if(a>=b&&a>=c)qa.pop();
else if(b>c){
a=b;
qb.pop();
}
else{
a=c;
qc.pop();
}
a+=q*(i-);
x=(long long)a*u/v;
qb.push(x-q*i);
qc.push(a-x-q*i);
if(i%t==)printf("%d ",a);
}
printf("\n");
for(int i=;!(qa.empty()&&qb.empty()&&qc.empty());i++){
a=frt(qa);
b=frt(qb);
c=frt(qc);
if(a>=b&&a>=c)qa.pop();
else if(b>c){
a=b;
qb.pop();
}
else{
a=c;
qc.pop();
}
a+=q*m;
if(i%t==)printf("%d ",a);
}
return ;
}
反思:
可能是没见过这种题吧,当时只想到了堆乱搞。也从一个侧面反映出自己做题太少,何况很多没见过这种题的也想到队列了呢……
D2T3 愤怒的小鸟
状压傻逼题。
话说各种被uoj hack,一开始eps设成1e-7被hack了,改成1e-8又被hack了,改成1e-9还被hack了,改成1e-10就A了,uoj这hack数据也太丧病了吧……
那个cnt_tbl是用来统计1数量卡边界用的,话说这玩意儿还挺好使……
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define popcnt(x) (cnt_tbl[(x)>>16]+cnt_tbl[(x)&65535])
using namespace std;
const int maxn=;
const double eps=1e-;
double dcmp(double);
double x[maxn],y[maxn];
int T,n,f[<<],cnt_tbl[]={};
int main(){
for(int i=;i<;i++)cnt_tbl[i]=cnt_tbl[i>>]+(i&);
scanf("%d",&T);
while(T--){
memset(f,,sizeof(f));
for(int s=;s<(<<);s++)f[s]=popcnt(s);
scanf("%d%*d",&n);
for(int i=;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);
for(int i=;i<=n;i++)for(int j=;j<i;j++)if(dcmp(x[i]-x[j])){
double a=(x[j]*y[i]-x[i]*y[j])/(x[i]*x[j]*(x[i]-x[j])),b=(x[j]*x[j]*y[i]-x[i]*x[i]*y[j])/(x[i]*x[j]*(x[j]-x[i]));
if(dcmp(a)>-)continue;
int w=;
for(int k=;k<=n;k++)if(!dcmp(a*x[k]*x[k]+b*x[k]-y[k]))w|=(<<(k-));
for(int s=;s<(<<n);s++)f[s|w]=min(f[s|w],f[s]+);
}
printf("%d\n",f[(<<n)-]);
}
return ;
}
double dcmp(double x){
if(fabs(x)<eps)return ;
return x<0.0?-:;
}
反思:
第一眼看成了搜索,尝试剪枝浪费了很多时间。自己弱不能怪社会。
这次联赛,算是对自己一年多OI生涯的检验。结果自己却挂了,失误很多。(不知道这些到底该说是失误还是能力问题。)
别的,真的不想再说什么了。不敢再想。
很快就是WC,然后就是省选。结果如何,只能看自己了。
Noip2016 总结&反思的更多相关文章
- Noip2016题解&总结
原文放在我的uoj博客上,既然新开了blog,那就移过来了 玩具谜题(toy) 送分题.没有什么好说的. 直接按照题目的要求模拟即可. 标准的noip式day1T1. #include<cstd ...
- NOIP2017总结与反思
手动博客搬家: 本文发表于20180213 00:01:05, 原地址https://blog.csdn.net/suncongbo/article/details/79319556 //由于12月生 ...
- NOIP2016滚粗记
想了好久还是决定要写... Day0 Day-5得感冒一直没好,连磕5天药丸. 早晨得知爸妈都要上班并不能送我到校的消息,于是计划10:30集合,定表8:45准备自己走去学校. 然后平常睡得有点晚,结 ...
- NOIp2016 Day1&Day2 解题报告
Day1 T1 toy 本题考查你会不会编程. //toy //by Cydiater //2016.11.19 #include <iostream> #include <cstd ...
- NOIp2016 游记
DAY -2 不要问我为什么现在就开了一篇博客. 本来想起个NOIp2016爆零记或者NOIp2016退役记之类的,但是感觉现在不能乱立flag了.所以就叫游记算了. 前几场模拟赛崩了一场又一场,RP ...
- [Noip2016]蚯蚓 D2 T2 队列
[Noip2016]蚯蚓 D2 T2 Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 关于2016.12.12——T1的反思:凸包的意义与应用
2016.12.12 T1 给n个圆,保证圆圆相离,求将圆围起来的最小周长.n<=100 就像上图.考场上,我就想用切线的角度来做凸包.以圆心x,y排序,像点凸包一样,不过用两圆之间的下切线角度 ...
- NOIP2016普及总结
---恢复内容开始--- 当时我说如果不出意外有385,结果就这么跪在了第二题,惨啊 本来以为发挥算正常,结果这发挥太不正常了 [T1] 水题啊[趴 注意下细节就好考你会不会写代码. [T2] 这题大 ...
随机推荐
- IDEA 中生成 Hibernate 逆向工程实践
谈起 Hibernate 应该得知道 Gavin King 大叔,他构建了 Hibernate ,并将其捐献给了开源社区. Hibernate 对象关系映射解决方案,为面向对象的领域模型到传统的关系型 ...
- Hibernate 缓存机制浅析
1. 为什么要用 Hibernate 缓存? Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源 ...
- map 函数----filter函数
# map 函数 l = (1,2,4,5,6,7,8,9,) print(list(map(lambda x:x**2,l)))#使用list类型((map函数(lambda 匿名函数定义x值:x* ...
- Jenkins插件安装和系统配置
前面我们只是把Jenkins部署在Tomcat中了,下面来看看Jenkins中的插件和一些基础的系统配置. 1.用户管理 我们一般的项目组肯定是由多名成员组成的,如何向Jenkins添加我们的成员呢? ...
- asp.net gridview 分页显示不出来的问题
使用gridview分页显示,在点击第二页的时候显示空白,无数据. 原因是页面刷新,绑定datatable未执行 解决方法: 1.将datatable设置为静态 2.在OnPageIndexChang ...
- jquery的几种ajax提交方式
$.post( url, function(data){ if(data.retcode == "0"){ alert(data.retmsg); }else{ alert(dat ...
- vue+webpack实践
最近使用了vue来做SPA应用,记一波学习笔记. 使用vue+webpack实现前端模块化. vuejs——轻量.学习成本低.双向绑定.无dom的操作.组件的形式编写 推荐官方文档 vue.js官方文 ...
- FFT 快速傅里叶变换浅析
终于补完坑了哈哈哈 这个东西很神奇,看了半天网上的解释和课件,研究了很长时间,算是大概明白了它的原理. 话不多说先上图. 我们要求的h(x)=f(x)*g(x),f(x)=Σai*x^i,g(x)=Σ ...
- 一次sql注入中转
今天一朋友丢过来一个注入让我看看 url:http://xxxx/ 先看下页面 常规测试一下 用户名输入:' or 1=1 -- - 密码任意 返回 用户名输入:' or 1=2 -- - 返回 基本 ...
- linux安装maven
一.下载maven 最新地址在:http://maven.apache.org/download.cgi 我下载的是:apache-maven-3.3.9-bin.tar.gz,是已经编译好的包 解压 ...