CODE FESTIVAL 2015 決勝(部分)

B - ダイスゲーム

题意:

给\(N\)个\(6\)个面骰子,然后问掷到概率最大的点数是多少。

分析:

随便打表随便发现是\(\huge\left\lfloor N*7/2 \right\rfloor\)

代码略。

C - 寿司タワー

题意:

给出\(N\)和一个长度为\(2N\)的\(01\)串,可以用\(1\)的花费移动其中的任意一个数字,询问使从头开始使每两个都含有\(0\)和\(1\)的最小交换次数。

例如:\(1001\)是一个合法的串,每两个指\((1,2),(3,4)....(2N-1,2N)\)都满足要求。

分析:

发现最多需要\(n\)次才可以交换得到正确的序列。

如果当下已经有一个\(0\)和\(1\)相邻,那么就可以减少一次交换次数。模拟即可。

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+7;
int n,ans;
char ch[MAXN];
int main()
{
cin>>n;
cin>>ch ;
ans=2*n;
for(int i=0;i<=2*n-1;i++)
{
if(ch[i]=='0'&&ch[i+1]=='1'||(ch[i]=='1'&&ch[i+1]=='0')){
ans-=2;
i++;
}
}
cout<<ans/2<<endl;
}

H - 焼肉の達人

题意:

给出\(N\)个区间以及大区间长度\(M\),选择部分区间对其进行区间覆盖,其中覆盖了两次及以上的部分不计算贡献,求最多覆盖大区间中的多少。

分析:

做法非常神仙,貌似也有线段树的做法?没有仔细看。

思考贡献的产生以及消失。当选择了一个区间时,这个区间内则都算贡献,当区间重合时,重合部分不算贡献。

观察可以得到如果我们将每一个整点都向前向后连边长度为\(1\),表示这一部分并没有计算贡献,然后对于一段区间,我们将其从头连到尾长度为0表示计算贡献,可以发现跑从\(0\)到\(n\)的最短路就是我们没有计算贡献的最小值,可以堆优化Dijkstra跑一跑。

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+7;
struct po
{
int nxt,to,dis;
}edge[MAXN<<3];
struct Node
{
int dis,id;
Node(){}
Node(int dis,int id) : dis(dis), id(id){}
bool operator < (const Node& rhs) const
{
return dis>rhs.dis;
}
};
int dis[MAXN],b[MAXN],head[MAXN],num;
inline void add_edge(int from,int to,int dis)
{
edge[++num].nxt=head[from];
edge[num].to=to;
edge[num].dis=dis;
head[from]=num;
}
void Dijkstra(int s)
{
memset(dis,100,sizeof(dis));
priority_queue<Node> q;
q.push(Node(0,s));
while(!q.empty()){
Node u=q.top();q.pop();
if(b[u.id]) continue;
b[u.id]=1;
for(int i=head[u.id];i!=-1;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]>u.dis+edge[i].dis){
dis[v]=u.dis+edge[i].dis;
q.push(Node(dis[v],v));
}
}
}
}
int n,m,s,t;
int main()
{
cin>>n>>m;
memset(head,-1,sizeof(head));
for(int i=0;i<m;i++){
add_edge(i,i+1,1);
add_edge(i+1,i,1);
}
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
add_edge(x,x+y,0);
}
Dijkstra(0);
cout<<m-dis[m]<<endl;
}

I - 風船ツリー

题意:

给出一个有\(N\)个节点的气球树,以及每个气球到它父亲的边的长度。

现在给出\(Q\)组询问,每组询问询问使气球树的最大高度为\(H\)最少需要删掉多少条边。

分析:

思维巧妙的线段树题目,也不知道\(ATCODER\)啥时候能出出来这么NB的线段树题了。

思考删边的时候,每个子树会互相影响,所以并不能简单地一删了之。

观察发现询问明显不可以使用数据结构什么的东西维护,这东西并不具有结合性质。所以估计是预处理之后进行$O(1)回答。

当只有一组询问时,考虑做法,可以先找到这个深度的所有点,然后枚举那些是要留下来的,删去其连向儿子的边以及所有其他子树有深度大于\(x\)的边。并且可以发现并没有比这更优的做法。

那么是否可以对所有深度进行预处理,然后直接回答询问?

发现不同的深度最多只有\(N\)个,离散化一下,然后我们就能使用线段树对其进行维护了。

可以先\(dfs\)一下求出每个点向下连出的边的条数以及以它为根的子树到达的最大深度是多少,然后从\(1\)号点开始,对于我们进入的节点,删去其所有的儿子,具体是将其子树的深度一直到\(n\)都在线段树上打上标记,然后当遍历一个新的节点时,将这个节点添加回来,重复刚才的操作,这样就可以\(O(nlogn)\)求出对于任何一个深度,我们需要删掉多少条边,然后每次询问就可以\(O(logn)\)查询了。

#include <bits/stdc++.h>
#define mid (l+r>>1)
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int MAXN=1e5+7;
int add[MAXN<<2],n,m,sz,ll[MAXN],q;
inline void pushup(int rt)
{
add[rt]=add[ls]+add[rs];
}
inline void update(int l,int r,int rt,int x,int k)
{
if(l==r) add[rt]+=k;
else {
if(x<=mid) update(l,mid,ls,x,k);
else update(mid+1,r,rs,x,k);
pushup(rt);
}
}
inline int query(int L,int R,int l,int r,int rt)
{
int ans=0;
if(L<=l&&r<=R) return add[rt];
if(L<=mid) ans+=query(L,R,l,mid,ls);
if(R>mid) ans+=query(L,R,mid+1,r,rs);
return ans;
}
struct po
{
int nxt,to;
}edge[MAXN];
int head[MAXN],mx[MAXN],dep[MAXN],cnt[MAXN],dp[MAXN],num;
vector<int> vx;
inline void add_edge(int from,int to)
{
edge[++num].nxt=head[from];
edge[num].to=to;
head[from]=num;
}
void dfs(int u,int fa)
{
mx[u]=dep[u];
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v!=fa){
dfs(v,u);
mx[u]=max(mx[u],mx[v]);
}
}
}
inline void solve(int u,int fa)
{
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v!=fa) update(0,n+2,1,mx[v],1);
}
dp[dep[u]]=min(dp[dep[u]],query(dep[u]+1,vx.size()+1,0,n+2,1));
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa) continue;
update(0,n+2,1,mx[v],-1);
solve(v,u);
update(0,n+2,1,mx[v],1);
}
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v!=fa) update(0,n+2,1,mx[v],-1);
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>ll[i];
dep[i]+=ll[i];
}
for(int i=2;i<=n;i++){
int p; cin>>p;
add_edge(p,i);
dep[i]+=dep[p];
vx.push_back(dep[i]);
} vx.push_back(dep[1]);
sort(vx.begin(),vx.end());
vx.erase(unique(vx.begin(),vx.end()),vx.end());
for(int i=1;i<=n;i++) dep[i]=lower_bound(vx.begin(),vx.end(),dep[i])-vx.begin(); for(int i=0;i<vx.size();i++) dp[i]=n;
dfs(1,1);
solve(1,1);
cin>>q;
for(int i=1;i<=q;i++){
int h;
cin>>h;
int pos=lower_bound(vx.begin(),vx.end(),h)-vx.begin();
if(pos==vx.size()||vx[pos]!=h) puts("-1");
else cout<<dp[pos]<<endl;
}
return 0;
}

CODE FESTIVAL 2015 決勝(部分)的更多相关文章

  1. 【赛时总结】 ◇赛时·IV◇ CODE FESTIVAL 2017 Final

    ◇赛时-IV◇ CODE FESTIVAL 2017 Final □唠叨□ ①--浓浓的 Festival 气氛 ②看到这个比赛比较特别,我就看了一看--看到粉粉的界面突然开心,所以就做了一下 `(* ...

  2. 【AtCoder】CODE FESTIVAL 2016 qual A

    CODE FESTIVAL 2016 qual A A - CODEFESTIVAL 2016 -- #include <bits/stdc++.h> #define fi first # ...

  3. 【AtCoder】CODE FESTIVAL 2016 qual B

    CODE FESTIVAL 2016 qual B A - Signboard -- #include <bits/stdc++.h> #define fi first #define s ...

  4. 【AtCoder】CODE FESTIVAL 2016 qual C

    CODE FESTIVAL 2016 qual C A - CF -- #include <bits/stdc++.h> #define fi first #define se secon ...

  5. CODE FESTIVAL 2017 qual B B - Problem Set【水题,stl map】

    CODE FESTIVAL 2017 qual B B - Problem Set 确实水题,但当时没想到map,用sort后逐个比较解决的,感觉麻烦些,虽然效率高很多.map确实好写点. 用map: ...

  6. CODE FESTIVAL 2017 qual B C - 3 Steps【二分图】

    CODE FESTIVAL 2017 qual B C - 3 Steps 题意:给定一个n个结点m条边的无向图,若两点间走三步可以到,那么两点间可以直接连一条边,已经有边的不能连,问一共最多能连多少 ...

  7. [AtCoder Code Festival 2017 QualB D/At3575] 101 to 010 - dp

    [Atcoder Code Festival 2017 QualB/At3575] 101 to 010 有一个01序列,每次可以选出一个101,使其变成010,问最优策略下能操作几次? 考虑像 11 ...

  8. Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution

    Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...

  9. CODE FESTIVAL 2017 qual B

    昨晚因为有点事就去忙了,没打后悔啊 A - XXFESTIVAL Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem ...

随机推荐

  1. SQL系统函数——系统信息

    1.查看信息1.1.查看编号和名称select @@SERVERNAME--SQL SERVER服务器的连接字符串,如:computername\instancenameselect @@SERVIC ...

  2. Webphere WAS 启动

    如果WebSphere是默认安装的话,是自带两个profile,Dmgr和AppSrv,只需要到指定目录下启动管理器和节点即可/usr/IBM/WebSphere/AppServer/profiles ...

  3. vue+node+mongoDB 火车票H5(三)---git提交时忽略不想提交的文件

    想要把项目通过git提交到GitHub上,但提交时并不想提交node_modules文件夹,这个文件夹太大 git 提交代码时不提交配置文件夹node_modules 在.gitignore文件中添加 ...

  4. form.submit 方法 并不会触发 form.onsubmit 事件

    做表单的时候发现一个奇怪的地方,总结下: form.submit 方法 并不会触发 form.onsubmit 事件,看代码: <body> <div class="con ...

  5. lookcss在深夜23:32开通

    CSS在深夜23:32开通 话说 哥也耐不住寂寞搞个网站玩玩.顺便记录一些生活和学习和工作和思想和神马的点点滴滴~ 好吧 ~本来想起个名字叫涉趣.谁知道百度了一下,已经有人叫这个名字了,杯具,貌似还是 ...

  6. 【Trello】使用指南

    一.谷歌浏览器插件推荐: Card Color Titles for Trello 在Card上现实标签的标题文字 Trellists: Trello Lists Master 允许展示和隐藏List ...

  7. Scala学习之For、Function、Lazy(4)

    1.for的使用 for的使用在各种编程语言中是最常见的,这里只是聊聊for在Scala中的表现形式,由于Scala语言是完全面向对象的,所以直接导致for的不同呈现,下面举几个例子说明一下 obje ...

  8. 查看linux目录剩余空间大小

    df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息,命令格式: df -hl   显示格式为: 文件系统 容量 已用 可用 已用% 挂载点 Filesystem S ...

  9. 并发编程7 管道&事件&信号量&进程池(同步和异步方法)

    1,管道 2.事件 3.信号量 4.进程池的介绍&&进程池的map方法&&进程池和多进程的对比 5.进程池的同步方法和异步方法 6.重新解释同步方法和异步方法 7.回调 ...

  10. Web 资源介绍

    软件体系结构 C/S, client/server 特点: 该结构的软件, 客户端和服务端都需要编写 开发成本较高,维护较为麻烦 好处: 客户端在本地可以分担一部分运算 B/S, browser/se ...