2017.11.04【NOIP提高组】模拟赛B组
来源:互联网 发布:epub制作软件安卓版 编辑:程序博客网 时间:2024/06/06 17:38
这次比赛我应该是100分的,但是只有20,就因为堆的down操作打错了。。。gg。
T1:【NOIP2017提高A组冲刺11.2】字典序
最水的一题了,而且也是唯一会做的一题。
就是拓扑排序,再用一个堆优化一下。就好了。
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;int last[100010],next[100010],tov[100010];int n,m,tot;int f[100010];int ans[100010];int num[100010];void insert(int x,int y){ tov[++tot]=y; next[tot]=last[x]; last[x]=tot; }void up(int x){ while((x>>1)>0&&f[x]<f[x>>1]) { swap(f[x],f[x>>1]); x=x>>1; }}void down(int x){ int k; while(((x<<1)<=tot&&f[x]>f[x<<1])||((x<<1)+1<=tot&&f[x]>f[(x<<1)+1])) { k=x<<1; if(k+1<=tot&&f[k+1]<f[k])++k; swap(f[x],f[k]); x=k; }}int main(){ freopen("dictionary.in","r",stdin); freopen("dictionary.out","w",stdout); scanf("%d%d",&n,&m); int i,x,y,j; for (i=1;i<=m;++i) { scanf("%d%d",&x,&y); insert(x,y); ++num[y]; } tot=0; for (i=1;i<=n;++i) if(num[i]==0) { f[++tot]=i; up(tot); } while(tot) { x=f[1]; ans[++ans[0]]=x;f[1]=f[tot--];down(1); i=last[x]; while(i) { y=tov[i]; --num[y]; if(!num[y]) { f[++tot]=y; up(tot); } i=next[i]; } } if (ans[0]<n) printf("-1"); else for (i=1;i<=ans[0];++i) printf("%d ",ans[i]); printf("\n");}
T2:【NOIP2017提高A组冲刺11.2】救赎
先用树形dp做出每一个节点为根的期望值。
然后可以递归每个点为根时的期望。这样它的父亲节点就会成为它的儿子。
然后推一推就对了。
#include<cstdio>#include<iostream>using namespace std;long long f[100010];int last[200010],next[200010],tov[200010];long long size[100010],son[100010];long long n,sum,tot,p=998244353;long long ans[100010];void insert(int x,int y){ tov[++tot]=y; next[tot]=last[x]; last[x]=tot; }long long ksm(long long x,long long y){ long long k=1,z=x; while (y>0) { if (y&1==1) k=(k*z)%p; y=y/2; z=(z*z)%p; } return k;}long long moon(long long x,long long y){return ((x-1)*((y-1)*ksm(y,p-2)%p))%p;}void dfs(long long x,int father){ size[x]=1; for (long long i=last[x];i;i=next[i]) { if(tov[i]!=father) { dfs(tov[i],x); size[x]+=size[tov[i]]; son[x]++; } } f[x]=moon(size[x],son[x])%p; sum=(sum+f[x])%p;}void dfs_ans(long long x,long long sf,long long sa,long long father){ long long son_now,son_next; if(x==1) son_now=son[x]; else son_now=son[x]+1; ans[x]=(sum-sf-f[x]+moon(n,son_now)%p+sa+p*2)%p; for (long long i=last[x];i;i=next[i]) { if(tov[i]!=father) { if(x==1) son_next=son[x]-1; else son_next=son[x]; dfs_ans(tov[i],(sf+f[x])%p,(sa+moon(n-size[tov[i]],son_next))%p,x); } }}int main(){ freopen("redemption.in","r",stdin); freopen("redemption.out","w",stdout); scanf("%lld",&n); long long i,x,y; for (i=1;i<=n-1;++i) { scanf("%lld%lld",&x,&y); insert(x,y); insert(y,x); } dfs(1,0); dfs_ans(1,0,0,0); for (i=1;i<=n;++i) printf("%lld\n",ans[i]);}
T3: 【NOIP2017提高A组冲刺11.2】失格
这题我改的最久。
我们可以发现这是一道最小生成树,然后就会发现不能暴力连边,我们可以只连刚好大于这个点的每个倍数的点。
然后最小生成树的排序部分用筒排。
就过了,细节注意。
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;struct cdy{int x,y,z;};struct cdy2{int x,y;};int n,tot;cdy2 p[100010],p1[100010];int ans,len;int a[100010];int f[100010];cdy edge[32000001];int num[10000001];int q[32000001],q1[32000001];int sum[10000001],chen[10000001];bool cmp2(cdy2 a,cdy2 b){return a.x<b.x;}int find(int x){ if(f[x]==x)return x; f[x]=find(f[x]); return f[x];}int main(){ freopen("autosadism.in","r",stdin); freopen("autosadism.out","w",stdout); scanf("%d",&n); int i,j,ma=0; tot=0; for (i=1;i<=n;++i) { scanf("%d",&p[i].x); ma=max(ma,p[i].x); p[i].y=i; } sort(p+1,p+1+n,cmp2); for (i=1;i<=n;++i) { if(p[i].x==p[i-1].x) { edge[++tot].x=p[i].y; edge[tot].y=p[i-1].y; edge[tot].z=0; } else { p1[++len].x=p[i].x; p1[len].y=p[i].y; } } int s,l,r,mid,x; l=2; for (i=1;i<=ma;++i) { if(i<=p1[l-1].x) chen[i]=l-1; else { chen[i]=l; ++l; } } for (i=1;i<=len-1;++i) { edge[++tot].x=p1[i].y; edge[tot].y=p1[i+1].y; edge[tot].z=p1[i+1].x%p1[i].x; x=i+1; for (j=2;j<=ma/p1[i].x;++j) { s=j*p1[i].x; if(chen[s]!=x) { l=chen[s]; edge[++tot].x=p1[i].y; edge[tot].y=p1[l].y; edge[tot].z=p1[l].x%p1[i].x; x=l; } } } ma=0; for (i=1;i<=tot;++i) { ++num[edge[i].z]; ma=max(ma,edge[i].z); } for (i=0;i<=ma;++i) sum[i]=sum[i-1]+num[i]; for (i=1;i<=tot;++i) { q[++q[0]]=sum[edge[i].z]; q1[q[q[0]]]=i; --sum[edge[i].z]; } for (i=1;i<=n;++i) f[i]=i; int xx,yy,ans,k; ans=k=0; for (i=1;i<=q[0];++i) { xx=find(edge[q1[i]].x); yy=find(edge[q1[i]].y); if(xx!=yy) { ++k; f[xx]=yy; ans+=edge[q1[i]].z; } if(k==n-1)break; } printf("%d\n",ans);}
阅读全文
0 0
- 2017.11.04【NOIP提高组】模拟赛B组
- 2017.11.25【NOIP提高组】模拟赛B组总结
- 2017.1.15【初中部 NOIP提高组】模拟赛B组
- 2017.3.18【NOIP提高组】模拟赛B组
- 2017.3.18【NOIP提高组】模拟赛B组
- 2017.3.18【NOIP提高组】模拟赛B组小结
- 2017.05.06【NOIP提高组】模拟赛B组
- 2017.06.24【NOIP提高组】模拟赛B组
- 2017.7.6总结【NOIP提高组】模拟赛B组
- 2017.07.06【NOIP提高组】模拟赛B组
- 2017.07.06【NOIP提高组】模拟赛B组小结
- 2017.07.07【NOIP提高组】模拟赛B组
- 2017.07.05【NOIP提高组】模拟赛B组小结
- 2017.07.07【NOIP提高组】模拟赛B组小结
- 2017.07.08【NOIP提高组】模拟赛B组
- 2017.07.08【NOIP提高组】模拟赛B组小结
- 2017.07.09【NOIP提高组】模拟赛B组
- 2017.07.9【NOIP提高组】模拟赛B组小结
- 6.17
- 后台监测程序关闭时执行代码
- 互联网技术栈 『Contents Catalog』
- 习题4(4.3)
- MVP操作RecyclerView多条目SpringView,OKHttp封装请求网络
- 2017.11.04【NOIP提高组】模拟赛B组
- regular expression matching --python
- 习题6.5
- rostopic hz 降低
- centos如何在官网下载以前的版本
- C/C++中如何计算程序运行时间?
- Navicat for Mysql 连接失败10061
- 静态图片人脸识别 OpenCV3,Python3实现
- RabbitMQ消息通信,生产者发送消息给指定的消费者的消息队列