Forewords

今年 USACO 的比赛变化挺大的,有部分分了,而且不再是固定十个点了(部分分只说这几个点满足这几个性质,以为十个点的我还高兴了一会,一提交,...),除此之外居然赛后还排名了。这场打得意外的顺手,但是还是有点小遗憾吧。样例强度还是有点不够高的,但 IOI 赛制嘛,也不能说啥。

T1 Milk Pumping

上来看错题,打了个最小生成树,结果别人只要一条路径给弄出个树来妥妥的超过最优解爆零。仔细看题了以后发现还行,就是个有限制的最短路,每个限制枚举一遍很暴力但是数据不是很大就不管这么多了。但是有两个点硬是 WA 了,有时间再调吧。

code

  1. #include<cstdio>
  2. #include<queue>
  3. #include<algorithm>
  4. #include<cstring>
  5. const int MAXN=1000+5;
  6. struct Edge{int u,v,w,f,next;};
  7. struct data
  8. {
  9. int u,w;
  10. bool operator < (const data &b) const
  11. {
  12. return w==b.w?u<b.u:w<b.w;
  13. }
  14. };
  15. int n,m,dis[MAXN],cnt;Edge edge[MAXN*2];int head[MAXN],u,v,w,f;bool vis[MAXN],visit[MAXN];
  16. std::priority_queue<data>pq;
  17. void AddEdge(int u,int v,int w,int f)
  18. {
  19. edge[++cnt].u=u;edge[cnt].v=v;edge[cnt].w=w;edge[cnt].f=f;
  20. edge[cnt].next=head[u];head[u]=cnt;
  21. }
  22. void Dijkstra(int limit)
  23. {
  24. data tmp,temp;
  25. memset(dis,0x3f3f3f,sizeof(dis));
  26. memset(vis,0,sizeof(vis));
  27. dis[1]=0;tmp.u=1;tmp.w=0;
  28. pq.push(tmp);
  29. while(!pq.empty())
  30. {
  31. temp=pq.top();pq.pop();
  32. if(vis[temp.u]) continue;
  33. vis[temp.u]=1;
  34. for(int i=head[temp.u];i;i=edge[i].next)
  35. {
  36. //printf("*%d ",edge[i].v);
  37. if(edge[i].f<limit) continue;
  38. if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w)
  39. {
  40. dis[edge[i].v]=dis[edge[i].u]+edge[i].w;
  41. tmp.u=edge[i].v;tmp.w=dis[edge[i].v];
  42. pq.push(tmp);
  43. }
  44. }
  45. }
  46. }
  47. int main()
  48. {
  49. freopen("pump.in","r",stdin);
  50. freopen("pump.out","w",stdout);
  51. scanf("%d %d",&n,&m);
  52. for(int i=1;i<=m;i++)
  53. {
  54. scanf("%d %d %d %d",&u,&v,&w,&f);
  55. AddEdge(u,v,w,f);AddEdge(v,u,w,f);
  56. }
  57. long long ans=0;
  58. for(int i=1;i<=cnt;i++)
  59. if(!visit[edge[i].f])
  60. {
  61. visit[edge[i].f]=1;
  62. Dijkstra(edge[i].f);
  63. //printf("[%lld]",dis[n]);
  64. if(dis[n]==dis[0]) continue;
  65. ans=std::max((double)ans,(double)((double)edge[i].f/dis[n])*1e6);
  66. }
  67. printf("%lld\n",ans);
  68. return 0;
  69. }

T2 Milk Visits

一眼树剖,打的时候发现还要加个主席树,于是就套上去了。第一次在比赛的时候写树套树诶。然后不知道想什么老是觉得 \(dep[x]<dep[y]\) 可以推出 \(id[x]<id[y]\),花了大量时间调,虽然也修了几个 bug 但是还是只过了那几个点。今天改完 A 了。

另外官方题解看上去很简洁的样子,找时间研究一下。

code

  1. #include<cstdio>
  2. #include<vector>
  3. #define MID (root->l+root->r)>>1
  4. const int MAXN=1e5+5;
  5. struct Edge{int u,v,next;};
  6. struct Tree{int l,r,val;Tree* ls;Tree* rs;};
  7. int n,m,u,v,x,y,z,linkid[MAXN],lcnt,dep[MAXN],t[MAXN],top[MAXN],heavy[MAXN],id[MAXN],type[MAXN];int head[MAXN],siz[MAXN],cnt,fa[MAXN];Edge edge[MAXN*2];Tree* root[MAXN];
  8. std::vector<int>son[MAXN];
  9. std::vector<int>nums[MAXN];
  10. void AddEdge(int u,int v)
  11. {
  12. edge[++cnt].u=u;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt;
  13. }
  14. int dag(int now,int fa)
  15. {
  16. int siz=0,maxid,maxv=0;
  17. // printf("depth of %d is %d\n",now,dep[now]);
  18. for(int i=head[now];i;i=edge[i].next)
  19. {
  20. if(edge[i].v!=fa)
  21. {
  22. ::fa[edge[i].v]=now;
  23. son[now].push_back(edge[i].v);
  24. dep[edge[i].v]=dep[now]+1;
  25. int ret=dag(edge[i].v,now);
  26. if(ret>maxv)
  27. {
  28. maxv=ret;
  29. maxid=edge[i].v;
  30. }
  31. siz+=ret;
  32. }
  33. }
  34. heavy[now]=maxid;
  35. siz++;
  36. ::siz[now]=siz;
  37. return siz;
  38. }
  39. void split(int now,int top,int lid)
  40. {
  41. id[now]=++cnt;
  42. type[cnt]=t[now];
  43. nums[t[now]].push_back(cnt);
  44. linkid[now]=lid;
  45. ::top[now]=top;
  46. if(!son[now].size()) return;
  47. split(heavy[now],top,linkid[top]);
  48. for(int i=0;i<son[now].size();i++)
  49. if(son[now][i]!=heavy[now]) split(son[now][i],son[now][i],++lcnt);
  50. }
  51. Tree* getNode()
  52. {
  53. Tree* ret=new Tree;
  54. ret->ls=ret->rs=NULL;
  55. ret->l=ret->r=ret->val=0;
  56. return ret;
  57. }
  58. void BuildTree(int l,int r,Tree* root)
  59. {
  60. root->l=l;root->r=r;root->val=0;
  61. if(l==r) return;
  62. Tree* ls=getNode();Tree *rs=getNode();int mid=MID;
  63. root->ls=ls;root->rs=rs;
  64. BuildTree(l,mid,ls);BuildTree(mid+1,r,rs);
  65. }
  66. void cpNode(Tree* src,Tree* to){to->l=src->l;to->r=src->r;to->val=src->val;to->ls=src->ls;to->rs=src->rs;}
  67. void Update(int target,Tree* base,Tree* root)
  68. {
  69. if(root->l==root->r) {root->val++;return;}
  70. int mid=MID;
  71. if(target<=mid)
  72. {
  73. root->ls=getNode();
  74. root->rs=base->rs;
  75. cpNode(base->ls,root->ls);
  76. Update(target,base->ls,root->ls);
  77. }
  78. else
  79. {
  80. root->ls=base->ls;
  81. root->rs=getNode();
  82. cpNode(base->rs,root->rs);
  83. Update(target,base->rs,root->rs);
  84. }
  85. root->val=root->ls->val+root->rs->val;
  86. }
  87. int Query(int l,int r,Tree* root)
  88. {
  89. if(l==root->l&&r==root->r) return root->val;
  90. int mid=MID;
  91. if(r<=mid) return Query(l,r,root->ls); else if(l>mid) return Query(l,r,root->rs); else return Query(l,mid,root->ls)+Query(mid+1,r,root->rs);
  92. }
  93. bool getResult(int x,int y,int z)
  94. {
  95. while(x!=y)
  96. {
  97. if(dep[x]<dep[y]) std::swap(x,y);
  98. if(linkid[x]==linkid[y]) return Query(id[y],id[x],root[z])-Query(id[y],id[x],root[z-1]);
  99. if(Query(id[top[x]],id[x],root[z])-Query(id[top[x]],id[x],root[z-1])) return 1;
  100. x=fa[top[x]];
  101. }
  102. return type[id[x]]==z;
  103. }
  104. int main()
  105. {
  106. scanf("%d %d",&n,&m);
  107. for(int i=1;i<=n;i++)
  108. scanf("%d",&t[i]);
  109. for(int i=1;i<n;i++)
  110. {
  111. scanf("%d %d",&u,&v);
  112. AddEdge(u,v);AddEdge(v,u);
  113. }
  114. fa[1]=1;
  115. dep[1]=1;
  116. linkid[1]=1;
  117. lcnt=1;
  118. dag(1,-1);
  119. cnt=0;
  120. split(1,1,1);
  121. root[0]=getNode();
  122. BuildTree(1,n,root[0]);
  123. for(int i=1;i<=n;i++)
  124. {
  125. root[i]=root[i-1];
  126. if(!nums[i].size()) {continue;}
  127. for(int j=0;j<nums[i].size();j++)
  128. {
  129. Tree* tmp=getNode();
  130. cpNode(root[i],tmp);
  131. Update(nums[i][j],root[i],tmp);
  132. root[i]=tmp;
  133. }
  134. }
  135. for(int i=1;i<=m;i++)
  136. {
  137. scanf("%d %d %d",&x,&y,&z);
  138. printf("%d",getResult(x,y,z));
  139. }
  140. return 0;
  141. }

T3 Moortal Cowmbat

一半的部分分给了字符串 DP,后面那一半怎么写就不知道了。

code

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. const int MAXN=30000+5;
  5. const int MAXK=50+5;
  6. const int MAXM=26+5;
  7. int dp[MAXN][MAXM][MAXK],minstart[MAXN],n,m,p,cost[MAXM][MAXM],a[MAXN];char str[MAXN];
  8. int main()
  9. {
  10. freopen("cowmbat.in","r",stdin);
  11. freopen("cowmbat.out","w",stdout);
  12. scanf("%d %d %d",&n,&m,&p);
  13. scanf("%s",str+1);
  14. if(p==1) {printf("0");return 0;}
  15. for(int i=1;i<=n;i++)
  16. a[i]=str[i]-'a'+1;
  17. for(int i=1;i<=m;i++)
  18. for(int j=1;j<=m;j++)
  19. scanf("%d",&cost[i][j]);
  20. for(int k=1;k<=m;k++)
  21. for(int i=1;i<=m;i++)
  22. for(int j=1;j<=m;j++)
  23. cost[i][j]=std::min(cost[i][j],cost[i][k]+cost[k][j]);
  24. memset(dp,0x3f3f3f,sizeof(dp));
  25. memset(minstart,0x3f3f3f,sizeof(minstart));
  26. minstart[1]=0;
  27. for(int i=1;i<=n;i++)
  28. for(int j=1;j<=m;j++)
  29. for(int k=0;k<p;k++)
  30. {
  31. //printf("%d %d %d %d %d\n",i,j,k,dp[i][j][k],minstart[i]);
  32. if(k==0)
  33. {
  34. dp[i+1][j][k+1]=std::min(dp[i+1][j][k+1],minstart[i]+cost[a[i]][j]);
  35. }
  36. else dp[i+1][j][k+1]=std::min(dp[i+1][j][k+1],dp[i][j][k]+cost[a[i]][j]);
  37. if(k==p-1) {minstart[i+1]=std::min(minstart[i+1],dp[i][j][k]+cost[a[i]][j]);dp[i+1][j][k]=std::min(dp[i+1][j][k],dp[i][j][k]+cost[a[i]][j]);}
  38. }
  39. printf("%d",minstart[n+1]);
  40. return 0;
  41. }

USACO 2019 December Contest 随记的更多相关文章

  1. 【USACO 2019 Feburary Contest】Gold

    模拟二月金组,三个半小时AK. USACO 2019 Feburary Contest, Gold T1 题意:给定一棵树,每个点有点权,每次可以进行以下操作之一: 更改一个点的点权 求某条路径上的点 ...

  2. USACO 2015 December Contest, Gold Problem 2. Fruit Feast

    Problem 2. Fruit Feast 很简单的智商题(因为碰巧脑出来了所以简单一,一 原题: Bessie has broken into Farmer John's house again! ...

  3. USACO 2015 December Contest, Platinum Problem Max Flow【树链剖分】

    题意比较难理解,就是给你n个点的树,然后给你m个修改操作,每一次修改包括一个点对(x, y),意味着将x到y所有的点权值加一,最后问你整个树上的点权最大是多少. 比较裸的树链剖分了,感谢Haild的讲 ...

  4. [USACO 2018 December Contest]作业总结

    t1 Convention 题目大意 每一头牛都有一个来的时间,一共有\(n\)辆车,求出等待时间最长的那头牛等待的最小时间. 解法 第一眼看到这道题还以为是\(2018noip\)普及组的t3魔鬼题 ...

  5. Usaco 2019 Jan Platinum

    Usaco 2019 Jan Platinum 要不是昨天老师给我们考了这套题,我都不知道usaco还有铂金这么一级. 插播一则新闻:杨神坚持认为铂金比黄金简单,原因竟是:铜 汞 银 铂 金(金属活动 ...

  6. AtCoder diverta 2019 Programming Contest 2

    AtCoder diverta 2019 Programming Contest 2 看起来我也不知道是一个啥比赛. 然后就写写题解QWQ. A - Ball Distribution 有\(n\)个 ...

  7. 【AtCoder】diverta 2019 Programming Contest 2

    diverta 2019 Programming Contest 2 A - Ball Distribution 特判一下一个人的,否则是\(N - (K - 1) - 1\) #include &l ...

  8. 【AtCoder】diverta 2019 Programming Contest

    diverta 2019 Programming Contest 因为评测机的缘故--它unrated了.. A - Consecutive Integers #include <bits/st ...

  9. diverta 2019 Programming Contest 2自闭记

    A 签到(a-b problem不用贴了吧,以后atcoder小于300分题均不贴代码) B 发现选择的p,q一定是其中两点间的距离,于是可以O(n2)枚举两点,再O(n2)判断,其实可以做到O(n3 ...

随机推荐

  1. 【C语言】极坐标转换为直角坐标

    写一个程序把极坐标(r,θ) (θ之单位为度)转换为直角坐标( X,Y). 转换公式是x=r.cosθ y=r.sinθ 程序输出:输出转换后的坐标. 弧度和角度的换算关系如下: 1弧度=180/π度 ...

  2. P1567

    最大子数组和问题,dp或者分治.. #include <bits/stdc++.h> #define rep(i, a, b) for(int i = a; i <= b; i++) ...

  3. 【代码审计】MenInfo文件包含漏洞

    代码审计是我之前一直不敢涉及的领域,它包含的知识面太广.最近才开始学习,前段时间写的第一篇代码审计的文章 更多的感觉像是一个黑盒测试.我也会尽量把文章写的通俗易懂.代码审计 0基础从大牛的蜕变 从这里 ...

  4. Spring Boot 使用 Aop 实现日志全局拦截

    前面的章节我们学习到 Spring Boot Log 日志使用教程 和 Spring Boot 异常处理与全局异常处理,本章我们结合 Aop 面向切面编程来实现全局拦截异常并记录日志. 在 Sprin ...

  5. 吴裕雄 python 神经网络——TensorFlow训练神经网络:全模型

    import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data INPUT_NODE = 784 ...

  6. 任意值运动框架Move模块 js

    function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name]; } else { retur ...

  7. 【原】python3.6安装python-dev

    [root@ci /usr/lib64/python3.6]# yum -y install python36-devel

  8. mybatis源码探索笔记-5(拦截器)

    前言 mybatis中拦截器主要用来拦截我们在发起数据库请求中的关键步骤.其原理也是基于代理模式,自定义拦截器时要实现Interceptor接口,并且要对实现类进行标注,声明是对哪种组件的指定方法进行 ...

  9. webstrom激活码

    转自https://www.cnblogs.com/mahmud/p/11847825.html 812LFWMRSH-eyJsaWNlbnNlSWQiOiI4MTJMRldNUlNIIiwibGlj ...

  10. Nginx安装部署!

    安装Nginx方法一:利用u盘导入Nginx软件包 二nginx -t 用于检测配置文件语法 如下报错1:配置文件43行出现错误 [root@www ~]# nginx -tnginx: [emerg ...