USACO 2019 December Contest 随记
Forewords
今年 USACO 的比赛变化挺大的,有部分分了,而且不再是固定十个点了(部分分只说这几个点满足这几个性质,以为十个点的我还高兴了一会,一提交,...),除此之外居然赛后还排名了。这场打得意外的顺手,但是还是有点小遗憾吧。样例强度还是有点不够高的,但 IOI 赛制嘛,也不能说啥。
T1 Milk Pumping
上来看错题,打了个最小生成树,结果别人只要一条路径给弄出个树来妥妥的超过最优解爆零。仔细看题了以后发现还行,就是个有限制的最短路,每个限制枚举一遍很暴力但是数据不是很大就不管这么多了。但是有两个点硬是 WA 了,有时间再调吧。
code
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
const int MAXN=1000+5;
struct Edge{int u,v,w,f,next;};
struct data
{
int u,w;
bool operator < (const data &b) const
{
return w==b.w?u<b.u:w<b.w;
}
};
int n,m,dis[MAXN],cnt;Edge edge[MAXN*2];int head[MAXN],u,v,w,f;bool vis[MAXN],visit[MAXN];
std::priority_queue<data>pq;
void AddEdge(int u,int v,int w,int f)
{
edge[++cnt].u=u;edge[cnt].v=v;edge[cnt].w=w;edge[cnt].f=f;
edge[cnt].next=head[u];head[u]=cnt;
}
void Dijkstra(int limit)
{
data tmp,temp;
memset(dis,0x3f3f3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[1]=0;tmp.u=1;tmp.w=0;
pq.push(tmp);
while(!pq.empty())
{
temp=pq.top();pq.pop();
if(vis[temp.u]) continue;
vis[temp.u]=1;
for(int i=head[temp.u];i;i=edge[i].next)
{
//printf("*%d ",edge[i].v);
if(edge[i].f<limit) continue;
if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w)
{
dis[edge[i].v]=dis[edge[i].u]+edge[i].w;
tmp.u=edge[i].v;tmp.w=dis[edge[i].v];
pq.push(tmp);
}
}
}
}
int main()
{
freopen("pump.in","r",stdin);
freopen("pump.out","w",stdout);
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d %d %d %d",&u,&v,&w,&f);
AddEdge(u,v,w,f);AddEdge(v,u,w,f);
}
long long ans=0;
for(int i=1;i<=cnt;i++)
if(!visit[edge[i].f])
{
visit[edge[i].f]=1;
Dijkstra(edge[i].f);
//printf("[%lld]",dis[n]);
if(dis[n]==dis[0]) continue;
ans=std::max((double)ans,(double)((double)edge[i].f/dis[n])*1e6);
}
printf("%lld\n",ans);
return 0;
}
T2 Milk Visits
一眼树剖,打的时候发现还要加个主席树,于是就套上去了。第一次在比赛的时候写树套树诶。然后不知道想什么老是觉得 \(dep[x]<dep[y]\) 可以推出 \(id[x]<id[y]\),花了大量时间调,虽然也修了几个 bug 但是还是只过了那几个点。今天改完 A 了。
另外官方题解看上去很简洁的样子,找时间研究一下。
code
#include<cstdio>
#include<vector>
#define MID (root->l+root->r)>>1
const int MAXN=1e5+5;
struct Edge{int u,v,next;};
struct Tree{int l,r,val;Tree* ls;Tree* rs;};
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];
std::vector<int>son[MAXN];
std::vector<int>nums[MAXN];
void AddEdge(int u,int v)
{
edge[++cnt].u=u;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt;
}
int dag(int now,int fa)
{
int siz=0,maxid,maxv=0;
// printf("depth of %d is %d\n",now,dep[now]);
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].v!=fa)
{
::fa[edge[i].v]=now;
son[now].push_back(edge[i].v);
dep[edge[i].v]=dep[now]+1;
int ret=dag(edge[i].v,now);
if(ret>maxv)
{
maxv=ret;
maxid=edge[i].v;
}
siz+=ret;
}
}
heavy[now]=maxid;
siz++;
::siz[now]=siz;
return siz;
}
void split(int now,int top,int lid)
{
id[now]=++cnt;
type[cnt]=t[now];
nums[t[now]].push_back(cnt);
linkid[now]=lid;
::top[now]=top;
if(!son[now].size()) return;
split(heavy[now],top,linkid[top]);
for(int i=0;i<son[now].size();i++)
if(son[now][i]!=heavy[now]) split(son[now][i],son[now][i],++lcnt);
}
Tree* getNode()
{
Tree* ret=new Tree;
ret->ls=ret->rs=NULL;
ret->l=ret->r=ret->val=0;
return ret;
}
void BuildTree(int l,int r,Tree* root)
{
root->l=l;root->r=r;root->val=0;
if(l==r) return;
Tree* ls=getNode();Tree *rs=getNode();int mid=MID;
root->ls=ls;root->rs=rs;
BuildTree(l,mid,ls);BuildTree(mid+1,r,rs);
}
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;}
void Update(int target,Tree* base,Tree* root)
{
if(root->l==root->r) {root->val++;return;}
int mid=MID;
if(target<=mid)
{
root->ls=getNode();
root->rs=base->rs;
cpNode(base->ls,root->ls);
Update(target,base->ls,root->ls);
}
else
{
root->ls=base->ls;
root->rs=getNode();
cpNode(base->rs,root->rs);
Update(target,base->rs,root->rs);
}
root->val=root->ls->val+root->rs->val;
}
int Query(int l,int r,Tree* root)
{
if(l==root->l&&r==root->r) return root->val;
int mid=MID;
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);
}
bool getResult(int x,int y,int z)
{
while(x!=y)
{
if(dep[x]<dep[y]) std::swap(x,y);
if(linkid[x]==linkid[y]) return Query(id[y],id[x],root[z])-Query(id[y],id[x],root[z-1]);
if(Query(id[top[x]],id[x],root[z])-Query(id[top[x]],id[x],root[z-1])) return 1;
x=fa[top[x]];
}
return type[id[x]]==z;
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&t[i]);
for(int i=1;i<n;i++)
{
scanf("%d %d",&u,&v);
AddEdge(u,v);AddEdge(v,u);
}
fa[1]=1;
dep[1]=1;
linkid[1]=1;
lcnt=1;
dag(1,-1);
cnt=0;
split(1,1,1);
root[0]=getNode();
BuildTree(1,n,root[0]);
for(int i=1;i<=n;i++)
{
root[i]=root[i-1];
if(!nums[i].size()) {continue;}
for(int j=0;j<nums[i].size();j++)
{
Tree* tmp=getNode();
cpNode(root[i],tmp);
Update(nums[i][j],root[i],tmp);
root[i]=tmp;
}
}
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&z);
printf("%d",getResult(x,y,z));
}
return 0;
}
T3 Moortal Cowmbat
一半的部分分给了字符串 DP,后面那一半怎么写就不知道了。
code
#include<cstdio>
#include<algorithm>
#include<cstring>
const int MAXN=30000+5;
const int MAXK=50+5;
const int MAXM=26+5;
int dp[MAXN][MAXM][MAXK],minstart[MAXN],n,m,p,cost[MAXM][MAXM],a[MAXN];char str[MAXN];
int main()
{
freopen("cowmbat.in","r",stdin);
freopen("cowmbat.out","w",stdout);
scanf("%d %d %d",&n,&m,&p);
scanf("%s",str+1);
if(p==1) {printf("0");return 0;}
for(int i=1;i<=n;i++)
a[i]=str[i]-'a'+1;
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
scanf("%d",&cost[i][j]);
for(int k=1;k<=m;k++)
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
cost[i][j]=std::min(cost[i][j],cost[i][k]+cost[k][j]);
memset(dp,0x3f3f3f,sizeof(dp));
memset(minstart,0x3f3f3f,sizeof(minstart));
minstart[1]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=0;k<p;k++)
{
//printf("%d %d %d %d %d\n",i,j,k,dp[i][j][k],minstart[i]);
if(k==0)
{
dp[i+1][j][k+1]=std::min(dp[i+1][j][k+1],minstart[i]+cost[a[i]][j]);
}
else dp[i+1][j][k+1]=std::min(dp[i+1][j][k+1],dp[i][j][k]+cost[a[i]][j]);
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]);}
}
printf("%d",minstart[n+1]);
return 0;
}
USACO 2019 December Contest 随记的更多相关文章
- 【USACO 2019 Feburary Contest】Gold
模拟二月金组,三个半小时AK. USACO 2019 Feburary Contest, Gold T1 题意:给定一棵树,每个点有点权,每次可以进行以下操作之一: 更改一个点的点权 求某条路径上的点 ...
- USACO 2015 December Contest, Gold Problem 2. Fruit Feast
Problem 2. Fruit Feast 很简单的智商题(因为碰巧脑出来了所以简单一,一 原题: Bessie has broken into Farmer John's house again! ...
- USACO 2015 December Contest, Platinum Problem Max Flow【树链剖分】
题意比较难理解,就是给你n个点的树,然后给你m个修改操作,每一次修改包括一个点对(x, y),意味着将x到y所有的点权值加一,最后问你整个树上的点权最大是多少. 比较裸的树链剖分了,感谢Haild的讲 ...
- [USACO 2018 December Contest]作业总结
t1 Convention 题目大意 每一头牛都有一个来的时间,一共有\(n\)辆车,求出等待时间最长的那头牛等待的最小时间. 解法 第一眼看到这道题还以为是\(2018noip\)普及组的t3魔鬼题 ...
- Usaco 2019 Jan Platinum
Usaco 2019 Jan Platinum 要不是昨天老师给我们考了这套题,我都不知道usaco还有铂金这么一级. 插播一则新闻:杨神坚持认为铂金比黄金简单,原因竟是:铜 汞 银 铂 金(金属活动 ...
- AtCoder diverta 2019 Programming Contest 2
AtCoder diverta 2019 Programming Contest 2 看起来我也不知道是一个啥比赛. 然后就写写题解QWQ. A - Ball Distribution 有\(n\)个 ...
- 【AtCoder】diverta 2019 Programming Contest 2
diverta 2019 Programming Contest 2 A - Ball Distribution 特判一下一个人的,否则是\(N - (K - 1) - 1\) #include &l ...
- 【AtCoder】diverta 2019 Programming Contest
diverta 2019 Programming Contest 因为评测机的缘故--它unrated了.. A - Consecutive Integers #include <bits/st ...
- diverta 2019 Programming Contest 2自闭记
A 签到(a-b problem不用贴了吧,以后atcoder小于300分题均不贴代码) B 发现选择的p,q一定是其中两点间的距离,于是可以O(n2)枚举两点,再O(n2)判断,其实可以做到O(n3 ...
随机推荐
- Java补强转
/* 对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围, 那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char). 1. 如果没有超过左侧 ...
- Centos 7源码编译安装 php7.1 之生产篇
Centos 7源码编译安装 php7.1 之生产篇 Published 2017年4月30日 by Node Cloud 介绍: 久闻php7的速度以及性能那可是比php5系列的任何一版本都要快,具 ...
- VS2017项目中使用代码连接MySQL数据库,以及进行数据添加
//头文件 #include "mysql.h" //函数定义 // 执行sql语句, 包括增加.删除.更新数据 bool ExecuteSql(MYSQL m_mysql,con ...
- No module named '_ctypes'
3.7版本需要一个新的包libffi-devel,安装此包之后再次进行编译安装即可. #yum install libffi-devel -y #make install 若在安装前移除了/usr/b ...
- @Value注解的使用
前提它需要在spring 管理的Bean中有效 (如@Service...) #{...} 此方式可以使用 SpEL 表达式如 #{30-15} ${...} 可以获取配置文件中的值 如 ${jwt. ...
- C语言笔记 11_头文件&强制类型转换&错误处理&递归
头文件 头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享.有两种类型的头文件:程序员编写的头文件和编译器自带的头文件. 在程序中要使用头文件,需要使用 C 预处理指 ...
- centos 6.5 编译安装glibc 2.14(附带中文乱码修正方案)
重要说明:glibc 是linux底层的c库,对系统而言是相当重要的,大部分软件的运行都会调用这个库. ==== 所以没有特殊需求不建议升级 升级后,此前通过源代码编译的软件运行可能出各种错 ...
- idea中springboot静态资源及页面跳转问题
1,静态资源放在resources/static下,html页面放在resources/templates下 2,在html中引入静态资源时,不用带static(对于路径来说是透明的) 3, 配置ht ...
- HYSBZ-2038小Z的袜子
作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从 ...
- Catalyst 2960 重启?
在实际的网络环境中,交换机的各种问题层出不穷,这里我遇到一个案例.关于Cisco 2960 S 交换机重启的问题. 故障描述:有那么几台C2960S交换机总是随机的重启. 原因:从show ver来 ...