2017-10-29离线赛总结
2017-10-29 22:34
155 查看
失分小结:
估分:220
实际分数:205
第二题的有15分切错了,但总体上能把自己切的大部分分数给弄到还是不错的
(虽然这次的发挥并不是特别好,感觉考试全程敲暴力)
这次考试裸分应该是有(256)[100+80+76]
其实切分是很重要的
像机房里另外几个大佬对于第三题都是切m=0,1,2
而像我这样的蒟蒻切了好多鬼畜的:性质2,m=0,…
切得太杂了,所以并不能得多少分
第一题模拟题,但把我转的晕头转向整整写了半个小时
第二题看起来就像是道树上差分
可以发现每个点的讯问的点是唯一的,
然后观察数据可以知道复杂度不会超过nlogn
利用树上差分,可以把每条路径对应的值在遍历树的过程中算出来
对于同一深度,答案先减去遍历该子树前的,在遍历后在加回去,
这样就可以得出该子树对应深度的人数(类似于”王子”)
对于l点走到lca,可以较为容易地利用差分算出
但lca到r,会略有不同
我们可以把从l到lca再到r的过程看做从一个很高的fa到r的过程
这个fa的深度就是dep[r]-len len=dep[r]+dep[l]-dep[fa]*2
由于dep[r]-len可能是负数,所以可以取模强制转化成正数
代码实现:
第三题算是一道入门的期望题,虽然考试时没有去想正解
dp定义是 在原来的教室还是另一个教室 上第几节课 用了几个申请
根据期望的线性性质,我们可以单独算每一步的贡献什么鬼玩意,然后就可以每次取最优
代码实现如下(小丑):
估分:220
实际分数:205
第二题的有15分切错了,但总体上能把自己切的大部分分数给弄到还是不错的
(虽然这次的发挥并不是特别好,感觉考试全程敲暴力)
这次考试裸分应该是有(256)[100+80+76]
其实切分是很重要的
像机房里另外几个大佬对于第三题都是切m=0,1,2
而像我这样的蒟蒻切了好多鬼畜的:性质2,m=0,…
切得太杂了,所以并不能得多少分
第一题模拟题,但把我转的晕头转向整整写了半个小时
第二题看起来就像是道树上差分
可以发现每个点的讯问的点是唯一的,
然后观察数据可以知道复杂度不会超过nlogn
利用树上差分,可以把每条路径对应的值在遍历树的过程中算出来
对于同一深度,答案先减去遍历该子树前的,在遍历后在加回去,
这样就可以得出该子树对应深度的人数(类似于”王子”)
对于l点走到lca,可以较为容易地利用差分算出
但lca到r,会略有不同
我们可以把从l到lca再到r的过程看做从一个很高的fa到r的过程
这个fa的深度就是dep[r]-len len=dep[r]+dep[l]-dep[fa]*2
由于dep[r]-len可能是负数,所以可以取模强制转化成正数
代码实现:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define M 300005 #define S 20 vector<int>edge[M],W[2][M],V[2][M]; int T[M],dep[M],Fa[S][M],ans[M],SumL[M],SumR[M]; int n,m; void Ldfs(int x,int f){ dep[x]=dep[f]+1; Fa[0][x]=f; for(int i=0;i<(int)edge[x].size();i++){ int y=edge[x][i]; if(y==f)continue; Ldfs(y,x); } } int LCA(int x,int y){ if(dep[x]>dep[y])swap(x,y); int len=dep[y]-dep[x]; for(int i=0;i<S;i++){ if(len&(1<<i))y=Fa[i][y]; } if(x==y)return x; for(int i=S-1;i>=0;i--){ if(Fa[i][x]!=Fa[i][y]){ x=Fa[i][x]; y=Fa[i][y]; } } return Fa[0][x]; } void Rdfs(int x){ int l=(dep[x]+T[x])%M; int r=(dep[x]-T[x]+M)%M; ans[x]-=SumL[l]+SumR[r]; for(int i=0;i<(int)edge[x].size();i++){ int y=edge[x][i]; if(y==Fa[0][x])continue; Rdfs(y); } for(int i=0;i<(int)W[0][x].size();i++)SumL[W[0][x][i]]+=V[0][x][i]; for(int i=0;i<(int)W[1][x].size();i++)SumR[W[1][x][i]]+=V[1][x][i]; ans[x]+=SumL[l]+SumR[r]; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); edge[x].pb(y); edge[y].pb(x); } Ldfs(1,0); for(int i=1;i<S;i++)for(int j=1;j<=n;j++)Fa[i][j]=Fa[i-1][Fa[i-1][j]]; for(int i=1;i<=n;i++)scanf("%d",&T[i]); for(int i=1;i<=m;i++){ int l,r,lca; scanf("%d%d",&l,&r); lca=LCA(l,r); int dis=dep[l]+dep[r]-2*dep[lca]; W[0][Fa[0][lca]].pb(dep[l]); V[0][Fa[0][lca]].pb(-1); W[0][l].pb(dep[l]); V[0][l].pb(1); W[1][lca].pb((M+dep[r]-dis)%M); V[1][lca].pb(-1); W[1][r].pb((M+dep[r]-dis)%M); V[1][r].pb(1); } Rdfs(1); for(int i=1;i<=n;i++)printf("%d ",ans[i]); puts(""); return 0; }
第三题算是一道入门的期望题,虽然考试时没有去想正解
dp定义是 在原来的教室还是另一个教室 上第几节课 用了几个申请
根据期望的线性性质,我们可以单独算每一步的贡献什么鬼玩意,然后就可以每次取最优
代码实现如下(小丑):
#include<bits/stdc++.h> using namespace std; #define N 305 #define M 2005 template<class _>void chk_mi(_ &x,_ y){if(x>y||x==-1)x=y;} double P[M],dp[2][M][M]; int dis ,Fi[M],Se[M]; int n,m,v,e; void init(){ scanf("%d%d%d%d",&n,&m,&v,&e); for(int i=1;i<=n;i++)scanf("%d",&Fi[i]); for(int i=1;i<=n;i++)scanf("%d",&Se[i]); for(int i=1;i<=n;i++)scanf("%lf",&P[i]); memset(dis,-1,sizeof(dis)); for(int i=1;i<=e;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); if(x==y)continue; chk_mi(dis[x][y],z); chk_mi(dis[y][x],z); } //floyd for(int k=1;k<=v;k++){ for(int i=1;i<=v;i++){ if(dis[i][k]==-1)continue; for(int j=1;j<=v;j++){ if(dis[k][j]==-1)continue; chk_mi(dis[i][j],dis[i][k]+dis[k][j]); } } } for(int i=1;i<=v;i++)dis[i][i]=0; for(int i=1;i<=v;i++)dis[0][i]=0; } void DP(){ for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)dp[1][i][j]=dp[0][i][j]=-1.0; dp[0][0][0]=0; for(int i=1;i<=n;i++){ for(int j=0;j<=m;j++){ if(j&&dp[0][i-1][j-1]!=-1)chk_mi(dp[1][i][j],dis[Fi[i-1]][Fi[i]]*(1-P[i])); if(j&&dp[1][i-1][j-1]!=-1)chk_mi(dp[1][i][j],dp[1][i-1][j-1]+ (dis[Fi[i-1]][Se[i]]*P[i]+dis[Fi[i-1]][Fi[i]]*(1-P[i]))*(1-P[i-1])); if(dp[0][i-1][j]!=-1)chk_mi(dp[0][i][j],dp[0][i-1][j]+dis[Fi[i-1]][Fi[i]]); if(dp[1][i-1][j]!=-1)chk_mi(dp[0][i][j],dp[1][i-1][j]+dis[Se[i-1]][Fi[i]]*P[i-1] +dis[Fi[i-1]][Fi[i]]*(1-P[i-1])); } } } int main(){ init(); DP(); double ans=-1; for(int i=0;i<=m;i++)if(dp[0] [i]!=-1)chk_mi(ans,dp[0] [i]); for(int i=0;i<=m;i++)if(dp[1] [i]!=-1)chk_mi(ans,dp[1] [i]); printf("%.2f\n",ans); return 0; }
相关文章推荐
- 离线赛20171017总结
- 1.C#开发winform 开发调运检疫离线制证功能。调用cLodop打印控件(NVelocity模块,生成HTML(包含cLodop打印控件的js),使用WebBrowser,展现网页)总结
- 2017-11-6离线赛总结(NOIP七连测第四场)
- 2017.11.08离线赛总结
- Google Docs离线功能的简单总结
- 2017.10.27离线赛总结
- 2017.10.16离线赛总结
- 2017-10-18离线赛总结
- 离线清除LINUX系统密码总结
- CDH5 Hadoop集群完全离线安装步骤总结
- 2017-10-21离线赛总结
- 2017-9-29离线赛总结
- 2017.10.30离线赛总结
- Hybrid APP的离线存储总结
- 20171009离线赛总结
- 2017-10-9离线赛总结
- [zz]完整的ubuntu镜像源/本地源/更新源/离线升级包!制作总结!
- 2017.10.19离线赛总结
- 2017-9-28离线赛总结
- 2017-10-24离线赛总结