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. EF 拉姆达 linq 帮助类

    (这个类是很早以前在网上找的,忘记出处请原谅.) 一.基本用法 [Route("List")] public ApiResult GetList(int page, int lim ...

  2. Angular JS 中 指令详解

    Angular JS的强大功能就在于其可以自定义很多指令,现在就指令做一下详细的剖析. 一个Angular js 指令(directive)需要指定一个唯一的名字(myDirective)和一个函数, ...

  3. RocketMQ中Producer的启动源码分析

    RocketMQ中通过DefaultMQProducer创建Producer DefaultMQProducer定义如下: public class DefaultMQProducer extends ...

  4. 【MySQL】日常小技巧汇总,更新中……

    创建表时修改自增主键,添加 AUTO_INCREMENT=<Number> ,例如: CREATE TABLE `table_name` ( `id` int(11) unsigned N ...

  5. 【iOS】iOS Error Domain=NSCocoaErrorDomain Code=3840 "未能完成操作。(“Cocoa”错误 3840。)"

    昨天遇到的这个问题,详细信息: ----->类和方法__25+[Manager noticeRequest:]_block_invoke399----->错误信息Error Domain= ...

  6. zabbix监控WEB网站性能

    一直在纠结用什么实例来给大家演示呢?想来想去还是官方的好,那我们怎么用zabbix监控web性能和可用性呢?我们这边分为几个步骤:打开网站.登陆.登陆验证.退出,一共4个小step,看实例. 检测流程 ...

  7. Placement_pools on Rados-GW

    The purpose of this test is to map a RadosGw Bucket to a specific Ceph pool. For exemple, if using a ...

  8. [Short-Circuit Constraint Violation]警告解决办法

    今天用Altium Designer16画PCB时候遇到一个问题,进行DRC检测,警告如下: [Short-Circuit Constraint Violation] GrayscaleSensor1 ...

  9. 缓存的有效期和淘汰策略【Redis和其他缓存】【刘新宇】

    缓存有效期与淘汰策略 有效期 TTL (Time to live) 设置有效期的作用: 节省空间 做到数据弱一致性,有效期失效后,可以保证数据的一致性 Redis的过期策略 过期策略通常有以下三种: ...

  10. Go基础语法学习

    Go语言基础 Go是一门类似C的编译型语言,但是它的编译速度非常快.这门语言的关键字总共也就二十五个,比英文字母还少一个,这对于我们的学习来说就简单了很多.先让我们看一眼这些关键字都长什么样: 下面列 ...