CF1187D. Subarray Sorting

想要把一个数x换到前面,x一定是小一点的值。由于B串是固定的,A串可调整,我们可以遍历B数组,对于B【i】,找到对于在A数组的位子pos,判断1~pos中,是不是A【pos】最小,如果是最小,说明可以换到最前面,把A【pos】的值变为inf后,继续遍历。

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f; const int MOD = 1e9+; /**********showtime************/ const int maxn = 3e5+;
int a[maxn], b[maxn];
queue<int>que[maxn];
int mn[maxn<<];
void update(int pos, int val, int le, int ri, int rt) {
if(le == ri) {
mn[rt] = val;
return ;
}
int mid = (le + ri) >> ;
if(mid >= pos) update(pos, val, le, mid, rt<<);
else update(pos, val, mid+, ri, rt<<|);
mn[rt] = min(mn[rt<<], mn[rt<<|]);
}
int query(int L, int R, int le, int ri, int rt) {
if(le >= L && ri <= R) {
return mn[rt];
}
int mid = (le + ri) >> ;
int res = inf;
if(mid >= L) res = min(res, query(L,R,le, mid, rt<<));
if(mid < R) res = min(res, query(L,R,mid+, ri, rt<<|));
return res;
}
void build(int le, int ri, int rt) {
if(le == ri) return ;
int mid = (le + ri) >> ;
build(le, mid, rt<<);
build(mid+, ri, rt<<|);
}
int main(){
int T; scanf("%d", &T);
while(T--) {
int n; scanf("%d", &n);
build(, n, );
for(int i=; i<=n; i++) scanf("%d", &a[i]), que[a[i]].push(i), update(i, a[i], , n, );
for(int i=; i<=n; i++) scanf("%d", &b[i]);
int flag = ;
for(int i=; i<=n; i++) {
if(!que[b[i]].empty()) {
int p = que[b[i]].front(); que[b[i]].pop();
if(query(, p, , n, ) < b[i]) flag = ;
else update(p, inf, , n, );
}
else flag = ;
}
for(int i=; i<=n; i++) {
while(!que[a[i]].empty()) que[a[i]].pop();
}
puts(flag?"YES":"NO");
}
return ;
}

E Tree Painting

树形DP,换根的转移。

#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl; typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x7f7f7f7f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+;
const double eps = 1e-;
/**********showtime************/
const int maxn = 2e5+;
vector<int> mp[maxn];
int sz[maxn];
ll ans = ;
int n;
void dfs(int u, int fa) {
sz[u] = ;
for(int i=; i<mp[u].size(); i++) {
int v = mp[u][i];
if(v == fa) continue;
dfs(v, u);
sz[u] += sz[v];
}
ans += sz[u];
}
void dfs2(int u, int fa, ll pre) { for(int i=; i<mp[u].size(); i++) {
int v = mp[u][i];
if(v == fa) continue; ll tmp = pre + n - 2ll * sz[v];
ans = max(ans, tmp); dfs2(v, u, tmp);
}
}
int main(){
scanf("%d", &n);
for(int i=; i<n; i++) {
int u,v;
scanf("%d%d", &u, &v);
mp[u].pb(v);
mp[v].pb(u);
}
dfs(, -);
dfs2(, -, ans);
printf("%lld\n", ans);
return ;
}

G Gang Up

网络流,搞好了。

这道题要把每个点拆成多个点表示不同的时间,每条边要对应多条道路,就是把1,4,9....变成容量为1,费用位1,3,5的边。

每个点要拆成100个点,就是最多会等待100的时间单位。因为第一个人最迟50个时间,那个第50个人就要100个时间到。

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f; const int mod = 1e9+; /**********showtime************/
const int maxn = ;
int st[maxn]; struct E{
int u,v,w,cost;
int nxt;
} edge[];
int gtot = ,head[maxn * ];
void addedge(int u, int v, int w, int cost) {
edge[gtot].v = v;
edge[gtot].w = w;
edge[gtot].cost = cost;
edge[gtot].nxt = head[u];
head[u] = gtot++; edge[gtot].v = u;
edge[gtot].w = ;
edge[gtot].cost = -cost;
edge[gtot].nxt = head[v];
head[v] = gtot++;
}
int dis[maxn * ],path[],vis[maxn*],pre[maxn*];
bool spfa(int s,int t){
memset(pre, - ,sizeof(pre));
memset(dis, inf,sizeof(dis));
memset(vis, , sizeof(vis)); queue<int>que; que.push(s);
vis[s] = ; dis[s] = ;
while(!que.empty()){
int u = que.front(); que.pop();
vis[u] = ;
for(int i=head[u]; ~i; i = edge[i].nxt){
int v = edge[i].v, val = edge[i].w, cost = edge[i].cost; if(val > && dis[v] > dis[u] + cost){
dis[v] = dis[u] + cost;
pre[v] = u; path[v] = i;
if(vis[v] == ){
vis[v] = ;
que.push(v);
}
}
}
}
return pre[t] != -;
}
int mcmf(int s,int t){
int flow = ,cost = ; while(spfa(s, t)){
int f = inf;
for(int i=t; i!=s; i = pre[i]){
f = min(f, edge[path[i]].w);
}
flow += f;
cost += f * dis[t];
for(int i=t; i!=s; i = pre[i]){
edge[path[i]].w -= f;
edge[path[i]^].w += f;
}
}
return cost;
}
int main(){
memset(head, -, sizeof(head));
gtot = ;
int n,m,k,c,d;
scanf("%d%d%d%d%d", &n, &m, &k, &c, &d);
for(int i=; i<=k; i++) {
int x;
scanf("%d", &x);
st[x]++;
} int s = , t = * n + ; for(int i=; i<=n; i++) {
for(int j=; j<=; j++) {
addedge((i-)*+j-, (i-)* + j, inf, c);
}
} for(int i=; i<=n; i++) {
if(st[i]) addedge(s, (i-)* + , st[i], );
} for(int i=; i<=; i++) addedge(i, t, inf, ); for(int i=; i<=m; i++) {
int u,v;
scanf("%d%d", &u, &v);
for(int j=; j<=; j++) {
for(int k=; k<=; k++){
addedge((u-)* + j - , (v-)* + j, , (k*k - (k-)*(k-)) * d + c);
addedge((v-)* + j - , (u-)* + j, , (k*k - (k-)*(k-)) * d + c);
}
}
} printf("%d\n", mcmf(s, t));
return ;
}

也可以两个点之间只建立一条道路,那么费用就需要根据流量重新计算。

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); } const int inf = 0x3f3f3f3f; const int mod = 1e9+; /**********showtime************/
const int maxn = ;
int st[maxn]; // Min-Cost Flow with positive convex edge weights
class MinCostFlow {
private:
struct Edge {
int a, b; // source, target
int f, c; // flow, capacity
ll m1, m2; // constants for cost Edge(int av, int bv, int cv, ll m1v, ll m2v)
: a(av), b(bv), f(), c(cv), m1(m1v), m2(m2v) {} // Get other end of edge
int getOth(int i) {
return i == a ? b : a;
}
// Get change in cost of pushing flow from i to getOth(i)
ll getCost(int i) {
int tf = f + (i == a ? : -);
if (tf < || tf > c) return inf;
return m1*(tf-f) + m2*(tf*tf-f*f);
}
void pushUnit(int i) {
f += (i == a ? : -);
}
}; vector<Edge> eds;
vector<vector<int> > conns;
public:
MinCostFlow(int n) : conns(n) {} void addEdge(int a, int b, int c, int m1, int m2) {
Edge tmp(a, b, c, m1, m2);
eds.push_back(tmp);
conns[a].push_back(eds.size() - );
conns[b].push_back(eds.size() - );
}
ll pushFlow(int source, int sink) {
int n = conns.size();
ll res = ; vector<int> pre(n);
vector<ll> cost(n);
while(true) {
for (int i = ; i < n; ++i) {
pre[i] = -;
cost[i] = inf;
}
cost[source] = ; priority_queue<pair<ll, int> > que;
que.push(pair<ll, int>(, source));
while(! que.empty()) {
int i = que.top().second;
ll v = -que.top().first;
que.pop();
if (v > cost[i]) continue;
for (auto j : conns[i]) {
int t = eds[j].getOth(i);
ll off = cost[i] + eds[j].getCost(i);
if (off < cost[t]) {
cost[t] = off;
pre[t] = j;
que.push(pair<ll, int>(-off, t));
}
}
}
int i = sink;
while(pre[i] != -) {
auto& ed = eds[pre[i]];
i = ed.getOth(i);
ed.pushUnit(i);
}
if (i != source) break;
res += cost[sink];
}
return res;
}
};
int main(){
int n,m,k,c,d;
// scanf("%d%d%d%d%d", &n, &m, &k, &c, &d);
R(n,m,k,c,d); for(int i=; i<=k; i++) {
int x;
scanf("%d", &x);
st[x]++;
} int s = , t = * n + ;
MinCostFlow fl(t + ); for(int i=; i<=n; i++) {
for(int j=; j<=; j++) {
fl.addEdge((i-)*+j-, (i-)* + j, inf, c, );
}
} for(int i=; i<=n; i++) {
if(st[i]) fl.addEdge(s, (i-)* + , st[i], , );
} for(int i=; i<=; i++) fl.addEdge(i, t, inf, , ); for(int i=; i<=m; i++) {
int u,v;
scanf("%d%d", &u, &v);
for(int j=; j<=; j++) {
fl.addEdge((u-)* + j - , (v-)* + j, k, c, d);
fl.addEdge((v-)* + j - , (u-)* + j, k, c, d);
}
} // printf("%d\n", fl.mcmf(s, t));
cout<<fl.pushFlow(s, t)<<endl;
return ;
}

【Edu 67】 补题记录的更多相关文章

  1. 【补题记录】ZJU-ICPC Summer Training 2020 部分补题记录

    补题地址:https://zjusummer.contest.codeforces.com/ Contents ZJU-ICPC Summer 2020 Contest 1 by Group A Pr ...

  2. 【JOISC 2020 补题记录】

    目录 Day 1 Building 4 Hamburg Steak Sweeping Day 2 Chameleon's Love Making Friends on Joitter is Fun R ...

  3. 【cf补题记录】Codeforces Round #608 (Div. 2)

    比赛传送门 再次改下写博客的格式,以锻炼自己码字能力 A. Suits 题意:有四种材料,第一套西装需要 \(a\).\(d\) 各一件,卖 \(e\) 块:第二套西装需要 \(b\).\(c\).\ ...

  4. 【cf补题记录】Codeforces Round #607 (Div. 2)

    比赛传送门 这里推荐一位dalao的博客-- https://www.cnblogs.com/KisekiPurin2019/ A:字符串 B:贪心 A // https://codeforces.c ...

  5. Codeforces 1214 F G H 补题记录

    翻开以前打的 #583,水平不够场上只过了五题.最近来补一下题,来记录我sb的调试过程. 估计我这个水平现场也过不了,因为前面的题已经zz调了好久-- F:就是给你环上一些点,两两配对求距离最小值. ...

  6. Yahoo Programming Contest 2019 补题记录(DEF)

    D - Ears 题目链接:D - Ears 大意:你在一个\(0-L\)的数轴上行走,从整数格出发,在整数格结束,可以在整数格转弯.每当你经过坐标为\(i-0.5\)的位置时(\(i\)是整数),在 ...

  7. Codeforces 补题记录

    首先总结一下前段时间遇到过的一些有意思的题. Round #474 (Div. 1 + Div. 2, combined)   Problem G 其实关键就是n这个数在排列中的位置. 这样对于一个排 ...

  8. 【补题记录】NOIp-提高/CSP-S 刷题记录

    Intro 众所周知原题没写过是很吃亏的,突然发现自己许多联赛题未补,故开此坑. 在基本补完前会持续更新,希望在 NOIp2020 前填完. 虽然是"联赛题",但不少题目还是富有思 ...

  9. ZJUT11 多校赛补题记录

    牛客第一场 (通过)Integration (https://ac.nowcoder.com/acm/contest/881/B) (未补)Euclidean Distance (https://ac ...

随机推荐

  1. python3 读取文件-2

    1.脚本 from sys import argv script,filename = argv#以读的模式打开txt文件txt = open(filename,'r+')print ("t ...

  2. 关于HTML的引入CSS文件问题

    一 html代码引用外部css文件时若css文件在本文件的父目录下的其他目录下,可使用绝对路径.此时路径要写为  “ ../ ”形式,如在tomcat下建立一个test文件,在该文件中建立两个文件 夹 ...

  3. Jmeter之CSS选择器/JQuery选择器关联

    选择器: CSS选择器或JQuery选择器是Jmeter支持的两种语法,下面对其两种语法进行简单介绍 CSS选择器 JQuery选择器 Chrome - 复制CSS选择器 Google Chrome在 ...

  4. TestNg中的断言你真的了解吗

    前言 在执行自动化测试脚本的时候,我们需要自动判断测试脚本执行完成后的实际结果是否与预期结果一致,这个时候就需要在程序运行之前写入断言,判断当前程序执行后是否正常. 关于TestNG断言分为两种: 软 ...

  5. 电信光猫带路由器(F452)的虚拟服务器端口映射

    现在电信宽带的光猫一般都自带路由器功能,为了方便运营商管理网络用户,电信公司插入了企业局域网,网络用户的光猫路由器都是这个局域网的节点.用户家里的电脑在网络中的结构位置一般如下所示: 互联网(公网)= ...

  6. Python flask构建微信小程序订餐系统

    第1章 <Python Flask构建微信小程序订餐系统>课程简介 本章内容会带领大家通览整体架构,功能模块,及学习建议.让大家在一个清晰的开发思路下,进行后续的学习.同时领着大家登陆ht ...

  7. Go“一个包含nil指针的接口不是nil接口”踩坑

    最近在项目中踩了一个深坑--"Golang中一个包含nil指针的接口不是nil接口",总结下分享出来,如果你不是很理解这句话,那推荐认真看下下面的示例代码,避免以后写代码时踩坑. ...

  8. spring学习笔记之---bean管理的注解方式

    bean管理的注解方式 (一)使用注解定义bean (1)常用注解 (2)实例 1.在pom.xml中进行配置 <dependencies> <dependency> < ...

  9. 理解MySQL(一)--MySQL介绍

    一.Mysql逻辑架构: 1. 第一层:服务器层的服务,连接\线程处理. 2. 第二层:查询执行引擎,MySQL的核心服务功能,包括查询解析.分析.优化和缓存,所有跨存储引擎的功能都在这一层实现. 3 ...

  10. Meta 用法汇总

    本文引自: http://blog.csdn.net/MR_LP/article/details/53607087 什么是 meta ? meta 是html语言head区的一个辅助性标签.也许你认为 ...