2018.10.16 NOIP模拟赛

时间:2h(实际)

期望得分:100+100+20

实际得分:100+100+100

T3:数据较水+时限较大+常数小+std也就是个暴力!!! = 暴力AC = 休闲半上午 = 辣鸡题目

A 购物shop

直接nth_element

因为\(m\leq100\),堆也是可以的。

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define mod 1000000000
typedef long long LL;
const int N=1e7+3; int A[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
} int main()
{
freopen("shop.in","r",stdin);
freopen("shop.out","w",stdout); int n=read(),m=read();
for(register int i=1,x=read(),y=read(); i<=n; ++i)
A[i]=(1ll*A[i-1]*y+x)%mod;//, printf("A[%d]=%d\n",i,A[i]);
std::nth_element(A+1,A+m,A+1+n);
LL ans=0;
for(int i=1; i<=m; ++i) ans+=A[i];
printf("%I64d\n",ans); return 0;
}

B 期望exp(DP 期望 按位计算)

对每位分别DP计算概率,乘上它的贡献就ok了。

#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define BIT 30
typedef long long LL;
const int N=1e5+5; int n,opt[N],A[N];
double P[N],P2[N];//p:exist p2:disappear
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline double readdb()
{
double x=0,y=0.1;register char c=gc();
for(; !isdigit(c)&&c!='.'; c=gc());
for(; isdigit(c); x=x*10+c-'0',c=gc());
for(c=='.'&&(c=gc()); isdigit(c); x+=(c-'0')*y,y*=0.1,c=gc());
return x;
}
namespace Subtask1
{
double Ans=0;
void DFS(int x,int val,double p)
{
if(x>n) {Ans+=p*val; return;}
DFS(x+1,opt[x]?(opt[x]==1?val|A[x]:val^A[x]):val&A[x],p*P[x]),
DFS(x+1,val,p*P2[x]);
}
void Main()
{
DFS(1,0,1), printf("%.1lf\n",Ans);
}
}
double Solve(int x)
{//p:exist p2:disappear
static double f[N][2];
f[0][0]=1, f[0][1]=0;
for(int i=1; i<=n; ++i)//,printf("f[%d][0]=%.7lf f[%d][1]=%.7lf\n",i-1,f[i-1][0],i-1,f[i-1][1]))
if(!opt[i])//&
if(A[i]>>x&1) f[i][0]=f[i-1][0], f[i][1]=f[i-1][1];
else f[i][0]=f[i-1][0]+f[i-1][1]*P[i], f[i][1]=f[i-1][1]*P2[i];
else if(opt[i]==1)//|
if(A[i]>>x&1) f[i][0]=f[i-1][0]*P2[i], f[i][1]=f[i-1][0]*P[i]+f[i-1][1];
else f[i][0]=f[i-1][0], f[i][1]=f[i-1][1];
else//^
if(A[i]>>x&1) f[i][0]=f[i-1][0]*P2[i]+f[i-1][1]*P[i], f[i][1]=f[i-1][0]*P[i]+f[i-1][1]*P2[i];
else f[i][0]=f[i-1][0], f[i][1]=f[i-1][1];
// printf("bit:%d p:%.7lf\n",x,f[n][1]);
return f[n][1];
} int main()
{
freopen("exp.in","r",stdin);
freopen("exp.out","w",stdout); n=read();
for(int i=1; i<=n; ++i) opt[i]=read();
for(int i=1; i<=n; ++i) A[i]=read();
for(int i=1; i<=n; ++i) P2[i]=readdb(),P[i]=1-P2[i];
// if(n<=22) return Subtask1::Main(),0;
double ans=0;
for(int i=0,pw2=1; i<=BIT; ++i) ans+=Solve(i)*pw2, pw2<<=1;
printf("%.1lf\n",ans); return 0;
}

C 魔法迷宫maze(状压 暴力)

因为边权只有\(2\)种,考虑预处理一次往上\(t\)步,那每个点的状态只有\(2^t\)种。

我们需要算\(f[s][k][rest]\),表示当前点\(x\)上面\(t\)条边的状态为\(s\),询问的\(K_i=k\),到\(x\)时剩余可走距离为\(rest\)。

记两种边权分别为\(mn,mx\),预处理复杂度\(O(2^t(t\times mx)^2)\)。令\(t=6\)好了。

这样当\(K_i\leq6mx\)时,一次至多走\(6\)步,可以直接这么\(6\)步\(6\)步往上跳。距离不足\(6\)时暴力跳。

\(K_i>6mx\)时,用上面预处理的每个点跳\(6\)步的位置及花费,不断每次跳\(6\)步。跳不了\(6\)步时,我们再预处理每个剩余可走距离为\(rest\in[1,6mx)\)时最远能到哪。

通过大量预处理,每次跳\(6\)步,就把暴力\(O(n^2)\)优化到了\(O(\frac{n^2}{6})\)啦,这就是std的做法啦。(mdzz)

\(u\to v\)的路径可以拆成\(u\to w\)和\(v\to w\),最后直接在\(w\)处合并一下就好了(就是两条路径剩余距离\(r_1+r_2\)除以\(k\)。因为如果能拼出\(k\)步自然可以取代\(k\)步,拼不出来的话那有剩余距离也没啥用)(其实还是感觉有点迷...)。

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=50005; int n,Enum,mx=0,mn=233,H[N],nxt[N<<1],to[N<<1],len[N<<1],fa[N],dep[N],dis[N],sz[N],son[N],top[N];
int pos[N][230],sta[N],p6[N],d6[N],f[(1<<6)+2][230][230],g[(1<<6)+2][230][230]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int w,int v,int u)
{
mx=std::max(mx,w), mn=std::min(mn,w);
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, len[Enum]=w;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, len[Enum]=w;
}
inline int LCA(int u,int v)
{
while(top[u]!=top[v]) dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]];
return dep[u]>dep[v]?v:u;
}
void DFS1(int x)
{
int mx=0; sz[x]=1;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x])
{
fa[v]=x, dep[v]=dep[x]+1, dis[v]=len[i], DFS1(v), sz[x]+=sz[v];
if(sz[v]>mx) mx=sz[v], son[x]=v;
}
}
void DFS2(int x,int tp)
{
top[x]=tp;
if(son[x])
{
DFS2(son[x],tp);
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x]&&v!=son[x]) DFS2(v,v);
}
}
void Init()
{
for(int i=1; i<=n; ++i)
if(dep[i]>=6)
{
int p=i,cost=0,s=0;
for(int j=0; j<6; ++j)
{
if(dis[p]==mx) s|=1<<j;
cost+=dis[p], p=fa[p];
}
sta[i]=s, p6[i]=p, d6[i]=cost;//p6:向上走6步能到哪
}
dis[1]=2e9;
for(int i=1; i<=n; ++i)
for(int t=0,res=0,p=i,lim=d6[i]; t<lim; ++t)
{
if(res>=dis[p]) res-=dis[p], p=fa[p];
++res, pos[i][t]=p;//pos:走剩余不足6mx的距离res能到哪
}
for(int s=0,lim=1<<6,l2=6*mx; s<lim; ++s)//上面6条边状态为s,k[i]=k,剩余rest,向上走6步到达的花费及剩下步数
for(int k=mx; k<=l2; ++k)
for(int rest=0; rest<=k; ++rest)
{
int res=rest,used=0;
for(int j=0,cost; j<6; ++j)
{
cost=s>>j&1?mx:mn;
if(res<cost) res=k, ++used;
res-=cost;
}
f[s][k][rest]=used, g[s][k][rest]=res;
}
}
void Solve(int x,int ed,int k,int &ans,int &res)
{
ans=0, res=0;
if(k<6*mx)
while(dep[x]-dep[ed]>5)
{
ans+=f[sta[x]][k][res], res=g[sta[x]][k][res];
x=p6[x];
}
else
while(dep[x]-dep[ed]>5)
{
if(res>=d6[x]) res-=d6[x], x=p6[x];
else x=pos[x][res], res=k, ++ans;
}
while(x!=ed)
{
if(res<dis[x]) res=k, ++ans;
res-=dis[x], x=fa[x];
}
} int main()
{
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout); n=read();
for(int i=1; i<n; ++i) AE(read(),read(),read());
DFS1(1), DFS2(1,1), Init();
int Q=read();
for(int i=1,u,v,w,k,ans1,ans2,res1,res2; i<=Q; ++i)
{
u=read(),v=read(),w=LCA(u,v),k=read();
Solve(u,w,k,ans1,res1), Solve(v,w,k,ans2,res2);
printf("%d\n",ans1+ans2-(res1+res2)/k);
} return 0;
}

考试代码

C

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=50005; int n,Enum,H[N],nxt[N<<1],to[N<<1],len[N<<1],fa[N],dis[N],dep[N],sz[N],son[N],top[N];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int w,int v,int u)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, len[Enum]=w;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, len[Enum]=w;
}
inline int LCA(int u,int v)
{
while(top[u]!=top[v]) dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]];
return dep[u]>dep[v]?v:u;
}
void DFS1(int x)
{
int mx=0; sz[x]=1;
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x])
{
fa[v]=x, dep[v]=dep[x]+1, dis[v]=len[i], DFS1(v), sz[x]+=sz[v];
if(sz[v]>mx) mx=sz[v], son[x]=v;
}
}
void DFS2(int x,int tp)
{
top[x]=tp;
if(son[x])
{
DFS2(son[x],tp);
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa[x]&&v!=son[x]) DFS2(v,v);
}
}
namespace Subtask1//辣鸡题目
{
int Solve(int k,int u,int v)
{
static int A[N];
int w=LCA(u,v),ans=1,rest=k;
// printf("%d,%d,%d k:%d\n",u,v,w,k);
while(u!=w)
{
if(dis[u]>rest) ++ans,rest=k;
rest-=dis[u], u=fa[u];
}
int t=0; for(int p=v; p!=w; p=fa[p]) A[++t]=p;
while(t)
{
if(dis[A[t]]>rest) ++ans,rest=k;
rest-=dis[A[t--]];
}
return ans;
}
void Main()
{
int Q=read();
for(int i=1; i<=Q; ++i) printf("%d\n",Solve(read(),read(),read()));
}
} int main()
{
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout); n=read();
for(int i=1; i<n; ++i) AE(read(),read(),read());
DFS1(1), DFS2(1,1);
if(n<=7000||1) return Subtask1::Main(),0; return 0;
}

10.16 NOIP模拟赛的更多相关文章

  1. 2018.10.16 NOIP模拟赛解题报告

    心路历程 预计得分:\(100 + 100 + 20 = 220\) 实际得分:\(100 + 100 + 30 = 230\) 辣鸡模拟赛.. T1T2都是一眼题,T3考验卡常数还只有一档暴力分. ...

  2. 10.17 NOIP模拟赛

    目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...

  3. 2016.10.30 NOIP模拟赛 day2 AM 整理

    题目+数据:链接:http://pan.baidu.com/s/1gfBg4h1 密码:ho7o 总共得了:130分, 1:100分  2:30分(只会这30分的暴力) 3:0(毫无思路) 虽然不高, ...

  4. 2016.10.30 NOIP模拟赛 day2 PM 整理

    满分:300分 直接全部爆零,真的是很坑啊! 10.30的题目+数据:链接:http://pan.baidu.com/s/1jHXLace 密码:i784 T1: 题目中的难点就是每次折叠的点可能应经 ...

  5. 2018.10.16 NOIP模拟 华莱士(并查集)

    传送门 按照题意模拟维护最小的环套树森林就行了. 然而考试的时候naivenaivenaive瞎写了一个错误的贪心. 代码

  6. 2017 10.25 NOIP模拟赛

    期望得分:100+40+100=240 实际得分:50+40+20=110 T1 start取了min没有用,w(゚Д゚)w    O(≧口≦)O T3 代码3个bug :数组开小了,一个细节没注意, ...

  7. 2018.10.03 NOIP+ 模拟赛 解题报告

    得分: \(30+5+0=35\)(考得真不咋滴) \(T1\):奥义商店(点此看题面) 以为很简单,对着这题想了一个多小时,最后果断打了个暴力交了... ... 看完题解发现其实也不是很难. 对于\ ...

  8. 2018.10.30 NOIp模拟赛 T1 改造二叉树

    [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他又和他人讨论 ...

  9. 【2019.7.16 NOIP模拟赛 T1】洗牌(shuffle)(找环)

    找环 考虑每次洗牌其实是一次置换的过程,而这样必然就会有循环出现. 因此我们直接通过枚举找出每一个循环,询问时只要找到环上对应的位置就可以了. 貌似比我比赛时被卡成\(30\)分的倍增简单多了? 代码 ...

随机推荐

  1. WebSphere的jython编码的一个坑

    was5.1版本,用"name=" in line这类判断字符串包含的方式时,系统会提示报错 TypeError: string member test needs char le ...

  2. windows环境用python修改环境变量的注意点(含代码)

    1.部分环境变量字段需要保留原来的值,只是做添加,不可以替换 2.Path和PATH对于python来说是一样的,也就是说存在名为Path的环境变量时,添加PATH的环境变量,会覆盖原有的Path环境 ...

  3. phpstudy中apache的默认根目录的配置

    默认配置文件是:vhosts.conf. 安装laravel后需要把根目录配置到public. 下面的配置需要在本地计算机的host文件配置域名,一个是“localhost”,一个是“www.goho ...

  4. 基于 OpenSSL 的 CA 建立及证书签发

    http://rhythm-zju.blog.163.com/blog/static/310042008015115718637/ 建立 CA 建立 CA 目录结构 按照 OpenSSL 的默认配置建 ...

  5. win7设置固定IP

    正文: 你必须知道你的路由器网关,一般是192.168.1.1(或192.168.0.1) 按传统的来:开始——控制面板——网络和共享中心——更改适配器设置.一般来讲,这里应该有两个图标,一个是有线网 ...

  6. sklearn,交叉验证中的分层抽样

    StratifiedKFold用法类似Kfold,但是他是分层采样,确保训练集,测试集中各类别样本的比例与原始数据集中相同. 例子: import numpy as np from sklearn.m ...

  7. mockito简单教程

    注:本文来源:sdyy321的<mockito简单教程> 官网: http://mockito.org API文档:http://docs.mockito.googlecode.com/h ...

  8. vue+element之多表单验证

    方法一:利用promise var p1=new Promise(function(resolve, reject) { this.$refs[form1].validate((valid) => ...

  9. hdu 1542 线段树+扫描线 学习

    学习扫描线ing... 玄学的东西... 扫描线其实就是用一条假想的线去扫描一堆矩形,借以求出他们的面积或周长(这一篇是面积,下一篇是周长) 扫描线求面积的主要思想就是对一个二维的矩形的某一维上建立一 ...

  10. (六)cxf处理一些Map等复杂类型

    前面讲的一些都是简单类型,cxf都支持.但是有些复杂类型,cxf是不支持,比如常用的Map类型: 下面我们在前面的实例基础上在加一个方法,比如我们现在有个需求,获取所有用用户以及对应的每个用户所有角色 ...