B:The Queue

题目大意:你要去办签证,那里上班时间是[s,t), 你知道那一天有n个人会来办签证,他们分别是在时间点ai来的。每个人办业务要花相同的时间x,问你什么时候来 排队等待的时间最少。  (如果你和某个人同时来排队,你会排在他后面)         所有时间为正整数。

题解:

首先可以模拟出 每个人的业务什么时候会办好,那么最优解要么是在第一个人来之前的一分钟来,即a1-1,要么是在某个人的业务刚办好的时候来。 分别求出要等待的时间即可。

注意如果有多个人同时来,那么只能在这些人里的最后的业务办好之后来。

代码:

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdlib>
#include <set>
#include <queue>
using namespace std; #define X first
#define Y second
#define Mod 1000000007
#define N 1000010
#define M 101 typedef long long ll;
typedef pair<int,int> pii; int n;
ll s,t,x,ans1,ans2;
ll v[N]; int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); scanf("%I64d%I64d%I64d",&s,&t,&x);
scanf("%d",&n); for (int i=;i<=n;i++) scanf("%I64d",&v[i]);
while (n && v[n]+x>t) n--;
if (n==)
{
printf("%I64d\n",s);
return ;
} ans1=v[]-; ans2=s-ans1; ll cur=s;
for (int i=;i<=n;i++)
{
if (v[i]<=cur) cur+=x;
else cur=v[i]+x;
if (i<n && v[i]==v[i+]) continue;
if (i<n)
{
ll tmp=v[i+]-,tt=max(0ll,cur-tmp);
if (tt<ans2) ans1=tmp,ans2=tt;
}
//cout<<i<<' '<<cur<<endl;
}
if (cur+x<=t)
{
ans1=cur,ans2=;
}
printf("%I64d\n",ans1);
return ;
}

C:Garland

题目大意:

给出一棵树,要求分成3部分,每个部分的点权和相同。

题解:

首先所有点的点权之和必须是3的倍数,否则无解。记s[x]为以x为根的子树点权和,tmp=所有点权和/3。假设我们选了u,v这两个点,并且切掉了它们到它们的父节点的边。那么符合要求的只有2种情况:

1.  s[u]=s[v]=tmp.   lca(u,v)!=u  && lca(u,v)!=v.

2.  s[u]=tmp*2,s[v]=tmp, lca(u,v)=u.

首先做一次dfs求出所有s[x]。

然后做第二次dfs:对于第2种情况,只要记录从根到当前节点是否存在s[u]=tmp*2的点, 如果存在,且当前节点s[v]=tmp,那么就找到了一种分割方案。

对于第1种情况, 对于当前节点v, 且s[v]=tmp,  我们需要知道是否存在一个点u,满足s[u]=tmp*2,且u不在 根到v的路径中。   这里用点小技巧, 假设dfs到了v,那么根到v的路径中的点都还在栈里, 所以只要考虑已经不在栈里的点u。  具体实现看代码。

代码:

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdlib>
#include <set>
#include <queue>
using namespace std; #define X first
#define Y second
#define Mod 1000000007
#define N 1000010
#define M 101 typedef long long ll;
typedef pair<int,int> pii; int n,t1,t2,rt,tmp,tt;
int father[N],v[N],s[N];
vector<int> g[N]; void Dfs(int x)
{
s[x]=v[x];
for (int i=;i<g[x].size();i++)
{
int y=g[x][i]; if (y==father[x]) continue;
Dfs(y); s[x]+=s[y];
}
} void Dfs2(int x,int pre)
{
if (pre && s[x]==tmp) t1=pre,t2=x;
if (tt && s[x]==tmp) t1=tt,t2=x;
for (int i=;i<g[x].size();i++)
{
int y=g[x][i]; if (y==father[x]) continue;
if (x!=rt && s[x]==tmp*) Dfs2(y,x);
else Dfs2(y,pre);
}
if (s[x]==tmp) tt=x;
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); scanf("%d",&n); int sum=;
for (int i=;i<=n;i++)
{
scanf("%d%d",&father[i],&v[i]);
if (father[i]) g[father[i]].push_back(i);
else rt=i;
sum+=v[i];
}
if (sum%){printf("-1\n"); return ;}
tmp=sum/; Dfs(rt);
Dfs2(rt,);
if (t1 && t2) printf("%d %d\n",t1,t2);
else printf("-1\n");
return ;
}

D:

有n瓶牛奶,分别还有ai天过期,每天最多喝k瓶。  超市里有m瓶牛奶,分别还有bi天过期, 问最多能从超市里买多少瓶牛奶,使得买来的牛奶加上本来已有的,都可以在过期之前喝完。

n<=100w.

题解:

显然要先买保质期长的牛奶,所以可以考虑二分答案。 如何判断可行性呢?  根据贪心策略,显然要先喝保质期短的牛奶。所以只要把牛奶按保质期排序就好。这里就涉及到将两个单调的序列合并成一个单调序列的问题。  数据范围100w应该是为了卡掉暴力sort合并的O(nlognlogn)解法.

代码:

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdlib>
#include <set>
#include <queue>
using namespace std; #define X first
#define Y second
#define Mod 1000000007
#define N 1000010
#define M 101 typedef long long ll;
typedef pair<int,int> pii; int n,m,k;
int a[N],q[N<<]; struct node
{
int v,id;
bool operator < (const node &t)const
{
return v<t.v;
}
}b[N]; bool check(int mid)
{
int i=,j=mid,cnt=;
while (i<n || j<m)
{
if (i>=n) q[cnt]=b[j].v,j++;
else if (j>=m) q[cnt]=a[i],i++;
else
{
if (a[i]<b[j].v) q[cnt]=a[i],i++;
else q[cnt]=b[j].v,j++;
}
if (cnt/k>q[cnt]) return false;
cnt++;
}
return true;
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); scanf("%d%d%d",&n,&m,&k);
for (int i=;i<n;i++) scanf("%d",&a[i]);
for (int i=;i<m;i++) scanf("%d",&b[i].v),b[i].id=i+;
sort(a,a+n);sort(b,b+m);
bool flag=true;
for (int i=;i<n;i++) if (a[i]<i/k) flag=false;
if (!flag){printf("-1\n"); return ;} int l=,r=m,mid,ans;
while (l<r)
{
mid=(l+r)>>;
if (check(mid)) r=mid;
else l=mid+;
} ans=m-l;
printf("%d\n",ans);
for (int i=m-ans;i<m;i++) printf("%d ",b[i].id);
printf("\n");
return ;
}

Codeforces Round #398 (Div. 2) BCD的更多相关文章

  1. Codeforces Round #398 (Div. 2)

    Codeforces Round #398 (Div. 2) A.Snacktower 模拟 我和官方题解的命名神相似...$has$ #include <iostream> #inclu ...

  2. Codeforces Round #398 (Div. 2) A. Snacktower 模拟

    A. Snacktower 题目连接: http://codeforces.com/contest/767/problem/A Description According to an old lege ...

  3. Codeforces Round #398 (Div. 2) C. Garland —— DFS

    题目链接:http://codeforces.com/contest/767/problem/C 题解:类似于提着一串葡萄,用剪刀剪两条藤,葡萄分成了三串.问怎样剪才能使三串葡萄的质量相等. 首先要做 ...

  4. Codeforces Round #398 (div.2)简要题解

    这场cf时间特别好,周六下午,于是就打了打(谁叫我永远1800上不去div1) 比以前div2的题目更均衡了,没有太简单和太难的...好像B题难度高了很多,然后卡了很多人. 然后我最后做了四题,E题感 ...

  5. Codeforces Round #398 (Div. 2) A,B,C,D

    A. Snacktower time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  6. Codeforces Round #398 (Div. 2) A B C D 模拟 细节 dfs 贪心

    A. Snacktower time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  7. Codeforces Round #398 (Div. 2) B,C

    B. The Queue time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  8. 【DFS】Codeforces Round #398 (Div. 2) C. Garland

    设sum是所有灯泡的亮度之和 有两种情况: 一种是存在结点U和V,U是V的祖先,并且U的子树权值和为sum/3*2,且U不是根,且V的子树权值和为sum/3. 另一种是存在结点U和V,他们之间没有祖先 ...

  9. 【枚举】【贪心】 Codeforces Round #398 (Div. 2) B. The Queue

    卡题意……妈的智障 一个人的服务时间完整包含在整个工作时间以内. 显然,如果有空档的时间,并且能再下班之前完结,那么直接输出即可,显然取最左侧的空档最优. 如果没有的话,就要考虑“挤掉”某个人,就是在 ...

随机推荐

  1. php实现简单视图模板(视图引擎)

    视图 视图,你所看见的部分. <?php echo 'hello, world'; 从简单开始理解 这就是个视图文件中的代码,没错就这么简单.视图,实际上是在 MVC 这种架构上提出的.MVC ...

  2. C++游戏界面不流畅的问题

    或许是我游戏玩多了,我突然发现,我的C++程序画面画面一顿一顿的,不流畅.肯定哪里不正确,要改. 奇怪啊,为什么我曾经,在我电脑上就不这么卡,就看不出画面一顿一顿的呢? 百度了,狗狗了,必应了,然而, ...

  3. kettle新手教程

     1.kettle介绍 kettle是一个ETL(Extract, Transform and Load抽取.转换.加载)工具,ETL工具在数据仓库项目使用很频繁,kettle也能够应用在下面一些 ...

  4. nagios监控mongodb

    nagios本身不提供监控mongodb的服务,需要安装插件 已经有大神写好的插件nagios_plugin-mongodb 地址https://github.com/mzupan/nagios-pl ...

  5. Java平时需要注意的事项

    1.String 相等 稍微有点经验的程序员都会用equals比较而不是用 ==,但用equals就真的安全了吗,看下面的代码 user.getName().equals("xiaoming ...

  6. Centos下输入法全角半角转换

    写个文档 ,发现输入法的设置框没有了,打出来的字全是全角,找了半天终于发现在设置的快捷键. 废话少说,Centos的全角半角转换快捷键是shift+space. 中英文标点的转换快捷键 ctrl+.

  7. Git——版本管理工具(一)

    Git 是一个分布式版本控制工具,它的作者 Linus Torvalds 是这样给我们介绍 Git  —— The stupid content tracker(傻瓜式的内容跟踪器) 1. Git 背 ...

  8. Array,Vector,List,Deque的区别与联系【转+改】

    数组 内存连续分配,长度大小固定,内置的最基础的数据结构之一.支持随机访问和随机存储. 该类型数据所占内存空间最小. Vector 是C++ STL中的一个容器.和数组类似,它拥有一段连续的内存空间, ...

  9. nginx和Tomcat集成后发生的重定向问题分析和解决

    nginx和Tomcat集成后发生的重定向问题分析和解决 Tomcat前端配置一个HTTP服务器应该是大部分应用的标配了,基本思路就是所有动态请求都反向代理给后端的Tomcat,HTTP服务器来处 理 ...

  10. Pattern Recognition and Machine Learning 模式识别与机器学习

    模式识别(PR)领域:     关注的是利⽤计算机算法⾃动发现数据中的规律,以及使⽤这些规律采取将数据分类等⾏动. 聚类:目标是发现数据中相似样本的分组. 反馈学习:是在给定的条件下,找到合适的动作, ...