2017 ZSTU寒假排位赛 #3
题目链接:https://vjudge.net/contest/147974#overview。
A题,费用流,不会。。跳过了。
B题,给一个图,问至少添加几条边能成为强连通图。显然缩点,要使得成为一个scc,任意一个点都要至少一个入度和出度,而一条边可以提供一个入度和出度,因为答案为max(入度为0的点,出度为0的点)。如果要求最多能添加几条使得还不是scc,则参照:最多添加几条使得还不是scc。如果是无向图问至少添加几条使得是边双联通,则参照:至少添加几条使得边双联通。
C题,线段树区间合并,貌似暑假的时候写过类似的,但是忘记了。。代码如下:
//#include <bits/stdc++.h>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define t_mid (l+r>>1)
#define ls (o<<1)
#define rs (o<<1|1)
#define lson ls,l,t_mid
#define rson rs,t_mid+1,r
using namespace std;
const int N = + ; int a[N];
// sub表示节点o的lcis的最长长度,l_val和r_val分别表示这个节点最左边和最右边的值分别是多少
// l_sub表示这个节点从最左边开始的最长的lcis的长度,r_sub同
int sub[N<<],l_val[N<<],r_val[N<<],l_sub[N<<],r_sub[N<<];
int T,n,q;
void up(int o,int l,int r)
{
int len = r - l + ;
l_val[o] = l_val[ls], r_val[o] = r_val[rs]; // 更新l_val,r_val
// 更新sub的值
sub[o] = max(sub[ls], sub[rs]);
if(r_val[ls] < l_val[rs]) sub[o] = max(sub[o], r_sub[ls]+l_sub[rs]); // 更新l_sub,r_sub
l_sub[o] = l_sub[ls];
if(l_sub[o] == len-len/ && r_val[ls] < l_val[rs]) l_sub[o] += l_sub[rs]; r_sub[o] = r_sub[rs];
if(r_sub[o] == len/ && r_val[ls] < l_val[rs]) r_sub[o] += r_sub[ls];
}
void build(int o,int l,int r)
{
if(l == r)
{
sub[o] = l_sub[o] = r_sub[o] = ;
l_val[o] = r_val[o] = a[l];
return ;
}
build(lson);
build(rson);
up(o,l,r);
}
void update(int o,int l,int r,int pos,int x)
{
if(l == r)
{
l_val[o] = r_val[o] = x;
return ;
}
if(pos <= t_mid) update(lson,pos,x);
else update(rson,pos,x);
up(o,l,r);
}
int query(int o,int l,int r,int ql,int qr)
{
if(l == ql && r == qr) return sub[o];
int ans = ;
if(qr <= t_mid) ans = query(lson,ql,qr);
else if(ql > t_mid) ans = query(rson,ql,qr);
else
{
ans = max(query(lson,ql,t_mid), query(rson,t_mid+,qr));
// 注意下面一行的两个min
if(r_val[ls] < l_val[rs]) ans = max(ans, min(r_sub[ls], t_mid-ql+) + min(l_sub[rs], qr-t_mid));
}
return ans;
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++) scanf("%d",a+i);
build(,,n);
while(q--)
{
char s[];
int x,y;
scanf("%s%d%d",s,&x,&y);
if(s[] == 'U') update(,,n,x+,y);
else printf("%d\n",query(,,n,x+,y+));
}
}
return ;
}
线段树区间合并
D题,分组背包,每组中,先选择一个,然后该组中其他的有三个选择,不选,或者从之前一组中转移(也就是放弃了这组中第一个选的而选这组中的这个),或者从这组中的转移(这组中的第一个要选)。代码如下:
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <stack>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int> pii;
const int N = + ; int n,m,k;
vector<pii> v[];
int dp[][+]; int main()
{
while(scanf("%d%d%d",&n,&m,&k) == )
{
for(int i=;i<=k;i++) v[i].clear();
for(int i=;i<=n;i++)
{
int pos,mo,val;
scanf("%d%d%d",&pos,&mo,&val);
v[pos].push_back(pii(mo,val));
}
int sum = ;
int flag = ;
for(int i=;i<=k;i++)
{
if(v[i].size() == )
{
flag = ;
break;
}
sort(v[i].begin(), v[i].end());
sum += v[i][].first;
}
if(sum > m || flag == )
{
printf("Impossible\n");
continue;
}
memset(dp,,sizeof dp);
for(int i=;i<=k;i++)
{
for(int j=;j<v[i].size();j++)
{
int w = v[i][j].first, val = v[i][j].second;
for(int mask=m;mask>=w;mask--)
{
if(j == ) dp[i][mask] = dp[i-][mask-w] + val;
else dp[i][mask] = max({dp[i][mask], dp[i-][mask-w]+val, dp[i][mask-w]+val});
}
}
}
printf("%d\n",dp[k][m]);
}
}
分组背包
E题,直接暴力枚举即可。完全背包也行。第一次wa是因为认为贪心先拿最小的最优,其实不然。例如:53--10,11,23。显然11的拿3个再拿10的两个比较好。
2017 ZSTU寒假排位赛 #3的更多相关文章
- 2017 ZSTU寒假排位赛 #7
题目链接:https://vjudge.net/contest/149498#overview. A题,水题,直接按照题意模拟一下即可. B题,我用的是线段树.大力用的差分标记(上次听zy说过,下次再 ...
- 2017 ZSTU寒假排位赛 #1
题目链接:https://vjudge.net/contest/147102#overview. A题:给出一堆的点,要找出两条垂直的直线,一条与x轴呈45度.-->使得所有的点到任意一条直线的 ...
- 2017 ZSTU寒假排位赛 #2
题目链接:https://vjudge.net/contest/147632#overview. A题,状态压缩一下然后暴力即可. B题,水题,略过. C题,有负数,前缀和不是单调的,因此不能用尺取法 ...
- 2017 ZSTU寒假排位赛 #8
题目链接:https://vjudge.net/contest/149845#overview. A题,水题. B题,给出 p个 第一个人的区间 和 q个第二个人的区间,问[l,r]中有多少个整数满足 ...
- 2017 ZSTU寒假排位赛 #6
题目链接:https://vjudge.net/contest/149212#overview. A题,水题,略过. B题,水题,读清题意即可. C题,数学题,如果把x表示成x=nb+m,则k=n/m ...
- 2017 ZSTU寒假排位赛 #5
题目链接:https://vjudge.net/contest/148901#overview. A题,排序以后xjbg即可. B题,弄个数组记录当前列是不是删除以及当前行是不是已经大于下一行然后乱搞 ...
- 2017 ZSTU寒假排位赛 #4
题目链接:https://vjudge.net/contest/148543#overview. A题:n个罪犯,每个人有一个犯罪值,现在要从里面选出连续的c个人,每个人的犯罪值都不能超过t,问选法的 ...
- Codeforces Round #341 (Div. 2)
在家都变的懒惰了,好久没写题解了,补补CF 模拟 A - Wet Shark and Odd and Even #include <bits/stdc++.h> typedef long ...
- 2017杭电ACM集训队单人排位赛 - 6
2017杭电ACM集训队单人排位赛 - 6 排名 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 59 1 X X 1 1 X X 0 1 ...
随机推荐
- java中锁的应用
锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized(重量级) 和 ReentrantLock(轻量级)等等 ) .这些已经写好提供的锁为我们开发提供了便利. ...
- 《深入理解 Java 虚拟机》学习 -- Java 内存模型
<深入理解 Java 虚拟机>学习 -- Java 内存模型 1. 区别 这里要和 JVM 内存模型区分开来: JVM 内存模型是指 JVM 内存分区 Java 内存模型(JMM)是指一种 ...
- springboot中的参数传递
1.前端传递到后端 1-1.js function add(){ var obj = {}; obj.parame_empname = $("#EMPNAME").val(); i ...
- C++遍历文件夹
struct _finddata_t { unsigned attrib; //文件属性 time_t time_create; //文件创建时间 time_t time_access; //文件上一 ...
- 【php设计模式】桥接模式
定义: 将抽象与实现分离,使它们可以独立变化.它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度. 角色: 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现 ...
- CSS精灵技术(sprite)
CSS技术的使用场景:有效的减少了服务器接收和发送请求的次数,css精灵是一种出来网页背景图像的方式,将一个页面设计到的所有零星背景图集中到一张大图中去,然后将大图应用于网页 .通过backgroun ...
- SpringCloud之Eureka注册中心原理及其搭建
一.Eureka简介 Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的.SpringCl ...
- Oracle使用基础
1.Oracle的基本概念: 数据库:存储数据的数据库,Oracle一般只有一个全局数据库 XE,ORCL. EX:Express Edition 速成版 ORCL:企业版 SID:SID是Syste ...
- 【转载】interpolation(插值)和 extrapolation(外推)的区别
根据已有数据以及模型(函数)预测未知区域的函数值,预测的点在已有数据范围内就是interpolation(插值), 范围外就是extrapolation(外推). The Difference Bet ...
- Jupyter安装和环境配置
配置: 1. 命令行启动 jupyter notebook 2. 也可以Anaconda直接启动 3. 设置token,如下图所示,命令行中输入 jupyter notebook list C:\Us ...