C - 2D Plane 2N Points

题意

二维平面上有\(N\)个红点,\(N\)个蓝点,一个红点和一个蓝点能配成一对当且仅当\(x_r<x_b\)且\(y_r<y_b\).

问最多能形成多少pair.

思路

无脑版本:可以匹配的连边,然后跑匈牙利。

正确的贪心姿势:对于所有的点按\(x\)从小到大排序,对于蓝点,要匹配的最优的红点即为 在其之前出现的 \(y\)小于它的 且\(y\)最大的 红点。用一个\(set\)维护红点的\(y\)坐标即可。

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 110
using namespace std;
typedef long long LL;
struct Point {
int x,y,type;
bool operator < (const Point& p) const { return x < p.x; }
}a[maxn<<1];
set<int> st;
int main() {
int n;
scanf("%d", &n);
F(i, 0, n) scanf("%d%d", &a[i].x, &a[i].y), a[i].type=0;
F(i, 0, n) scanf("%d%d", &a[n+i], &a[n+i].y), a[n+i].type=1;
sort(a, a+(n<<1));
int ans=0;
F(i, 0, n<<1) {
if (a[i].type) {
auto it = st.lower_bound(a[i].y);
if (it==st.begin()) continue;
else st.erase(--it), ++ans;
}
else {
st.insert(a[i].y);
}
}
printf("%d\n", ans);
return 0;
}

D - Two Sequences

题意

两个序列\(A,B\),对所有的\(A_i+B_j\)求异或和。

思路

按位考虑,不妨考虑第\(k\)位。

怎么才能知道第\(k\)位是\(0\)还是\(1\)呢?

即考虑所有的和当中有奇数个还是偶数个第\(k\)位是\(1\)。

对于某个和,怎么知道其第\(k\)位是\(0\)还是\(1\)呢?

注意到,高于\(k\)位的都不会产生影响,因此,只需要考虑\(a_i\%2^{k+1}\)与\(b_i\%2^{k+1}\)的和。若该和\(s\)满足\(2^k\leq s\lt 2\cdot2^k\)或者\(3\cdot2^k\leq s\lt 4\cdot2^k\),则该位为\(1\).

所以对于每个\(a_i\%k\),将\(b_i\%k\)排序,二分即可。

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 200010
using namespace std;
typedef long long LL;
int a[maxn], b[maxn], bb[maxn];
int main() {
int n;
scanf("%d", &n);
F(i, 0, n) scanf("%d", &a[i]);
F(i, 0, n) scanf("%d", &b[i]);
int mod=1, ans=0;
F(k, 0, 29) {
F(i, 0, n) bb[i] = b[i] % (mod<<1);
sort(bb, bb+n);
int cnt=0;
F(i, 0, n) {
int temp=a[i]%(mod<<1);
int p1=lower_bound(bb, bb+n, mod-temp)-bb,
p2=lower_bound(bb, bb+n, (mod<<1)-temp)-bb,
p3=lower_bound(bb, bb+n, mod*3-temp)-bb,
p4=lower_bound(bb, bb+n, (mod<<2)-temp)-bb;
cnt += p2-p1+p4-p3;
}
ans += cnt&1 ? mod : 0;
mod <<= 1;
}
printf("%d\n", ans);
return 0;
}

E - Both Sides Merger

题意

对一个序列能够进行两种操作:

  1. 选取开头或结尾的元素,直接删去;
  2. 选取中间的某个元素,用它两旁的元素之和代替它,再去掉两旁的两个元素。

现要求经过若干次操作,只剩下一个元素,且值最大,输出操作。

思路

不难发现,所有选取的元素在原序列中的奇偶性相同;

反过来,只要所有元素在原序列中奇偶性相同,即可构造出相应的操作序列。

只取正数很容易就能得到最优取法。

// 注意特判全为负数的情况

现在考虑一个取法\(d_0,d_1,\ldots,d_k\),首先将开头\(\lt d_0\)和结尾\(\gt d_k\)的一系列元素删去,接下来考虑对中间的元素进行的操作。

对于\(d_0\)至\(d_1\)一段,因为奇偶性相同,所以中间必然夹着奇数个元素,每次取最中间的即可将序列不断地往中间缩,直至\(d_0\)与\(d_1\)合并。接下来再作为一个整体与\(d_2\)合并,依次类推。

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 1010
using namespace std;
typedef long long LL;
int d1[maxn], d2[maxn], tot1, tot2, tot, n, a[maxn];
int* d;
vector<int> ans;
void solve() {
F(i, 1, d[0]) ans.push_back(1);
dF(i, n, d[tot-1]) ans.push_back(i-d[0]+1);
F2(i, 1, tot-1) {
int lim=(d[i]-d[i-1])>>1;
dF(j, 1+lim, 1) ans.push_back(j);
}
}
int main() {
scanf("%d", &n);
int p=1;
F2(i, 1 ,n) {
scanf("%d", &a[i]);
p = a[i] > a[p] ? i : p;
}
LL sum;
if (a[p]<=0) d1[tot++]=p, sum=a[p], d=d1;
else {
LL sum1=0, sum2=0;
for (int i = 1; i <= n; i += 2) if (a[i]>0) d1[tot1++]=i, sum1+=a[i];
for (int i = 2; i <= n; i += 2) if (a[i]>0) d2[tot2++]=i, sum2+=a[i];
d = sum1 < sum2 ? d2 : d1;
tot = sum1 < sum2 ? tot2 : tot1;
sum = max(sum1, sum2);
}
solve();
printf("%lld\n%d\n", sum, ans.size());
for (auto x : ans) printf("%d\n", x);
return 0;
}

F - Two Faced Edges

题意

给定一个有向图,每次将一条边方向反转,问这个操作是否改变了图中的强连通分量数,

思路

结论

假设原有边\(a_i\rightarrow b_i\),考虑接下来两个命题:

1, 原图中能从\(b_i\)走到\(a_i\),

2. 原图中删去了\(a_i\rightarrow b_i\)边后仍能从\(a_i\)走到\(b_i\)。

则图中的强连通分量数不改变 当且仅当 命题1与命题2同真假。

下面考虑命题2如何\(check\).

考虑将从\(a_i\)出去的边标号,先沿着边的标号从小到大进行\(dfs\),对图中每个点的标记则为其第一次被访问是来自哪条边的行为;再从大到小进行\(dfs\),对图中每个点的标记则为其最后一次被访问是来自哪条边的行为。

// 两个标记即相当于前缀与后缀的作用

如果这两个标记不都等于删去的边的标号(若都等于,则意味着该边为必经边),则删去该边仍能走到。

至于命题1,可以建立在命题2的基础上,也可以直接每个点一次\(dfs\).

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 1010
#define maxm 200010
using namespace std;
typedef long long LL;
int f[maxn][maxn][2], vis[maxn<<1], T;
struct node {int to, id; };
vector<node> edge[maxn];
pair<int, int> E[maxm];
void dfs(int u, int src, int id, int type) {
f[src][u][type] = id; vis[u] = T;
for (auto& e : edge[u]) {
int v = e.to;
if (vis[v]!=T) dfs(v, src, id, type);
}
}
void work(int src) {
++T; vis[src] = T;
for (auto& e : edge[src]) {
int v = e.to;
if (vis[v]!=T) dfs(v, src, e.id, 0);
} reverse(edge[src].begin(), edge[src].end());
++T; vis[src] = T;
for (auto& e : edge[src]) {
int v = e.to;
if (vis[v]!=T) dfs(v, src, e.id, 1);
}
}
int main() {
int n, m, u, v;
scanf("%d%d", &n ,&m);
F2(i, 1, m) {
scanf("%d%d", &u, &v);
edge[u].push_back({v, i});
E[i] = {u, v};
}
F2(i, 1, n) work(i);
F2(i, 1, m) {
int u = E[i].first, v = E[i].second;
if (f[v][u][0]!=0 ^ (f[u][v][0]!=i||f[u][v][1]!=i)) puts("diff");
else puts("same");
}
return 0;
}

AtCoder Regular Contest 092 C D E F的更多相关文章

  1. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  2. AtCoder Regular Contest 090 C D E F

    C - Candies 题意 求左上角走到右下角最大的数字和. 思路 直接\(dp\) Code #include <bits/stdc++.h> #define maxn 110 usi ...

  3. 思维定势--AtCoder Regular Contest 092 D - Two Sequences

    $n \leq 100000$的俩序列,数字范围$2^{28}$,问所有$a_i+b_j$的$n^2$个数字的异或和. 这种东西肯定是按位考虑嘛,从低位开始然后补上进位.比如说第一位俩串分别有$c$个 ...

  4. Atcoder Regular Contest 092 D - Two Faced Edges(图论+bitset 优化)

    Atcoder 题面传送门 & 洛谷题面传送门 orz ymx,ymx ddw %%% 首先既然题目要我们判断强连通分量个数是否改变,我们首先就将原图 SCC 缩个点呗,缩完点后我们很自然地将 ...

  5. AtCoder Regular Contest 092 C - 2D Plane 2N Points(二分图匹配)

    Problem Statement On a two-dimensional plane, there are N red points and N blue points. The coordina ...

  6. Atcoder Regular Contest 092 A 的改编

    原题地址 题目大意 给定平面上的 $n$ 个点 $p_1, \dots, p_n$ .第 $i$ 点的坐标为 $(x_i, y_i)$ .$x_i$ 各不相同,$y_i$ 也各不相同.若两点 $p_i ...

  7. AtCoder Regular Contest 092 B Two Sequences

    题目大意 给定两个长为 $n$ 个整数序列 $a_1, \dots, a_n$ 和 $b_1, \dots, b_n$ .求所有 $a_i + b_j$($1\le i, j\le n$)的 XOR ...

  8. AtCoder Regular Contest 092 Two Sequences AtCoder - 3943 (二进制+二分)

    Problem Statement You are given two integer sequences, each of length N: a1,…,aN and b1,…,bN. There ...

  9. AtCoder Regular Contest 092 2D Plane 2N Points AtCoder - 3942 (匈牙利算法)

    Problem Statement On a two-dimensional plane, there are N red points and N blue points. The coordina ...

随机推荐

  1. 微信营销 推广 会议签到 活动签到 复用微信3D动画签到系统

    适用场合 本软件适合各行各业,尤其世界500强上市公司,推广产品,聚集微信粉丝和人气.如大型展销会,新产品发布,主题活动推广,年会晚会等.各种商业和演出场合. 软件有试用版可供下载试用. 特色功能 顾 ...

  2. Qt 汽车仪表再次编写,Widget,仪表显示,绘制界面

    感谢某网友提供UI让我练练手,上目前的效果 还在晚上,代码等后面在贴出来,就是出来显摆一下

  3. Linux通配符与特殊符号知识大全汇总

    符号 作用 Linux通配符 * 匹配任意(0个或多个)字符或字符串,包括空字符串 ? 匹配任意1个字符,有且只有一个字符 [abcd] 匹配abcd中任何一个字符,abcd也可是其他任意不连续字符 ...

  4. kill命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/wangcp-2014/p/5146343.html 1.命令格式: kill[参数][进程号] 2.命令功能: 发送指 ...

  5. linux备忘录-日志档案

    linux的日志档案 linux的日志档案记录系统或程序在运行过程中产生的一些信息,例如事件的记录,错误的记录等等.特别是在发生错误时,我们可以通过日志档案找到错误发生的根源,例如当我们无法启动邮件服 ...

  6. ACM训练大纲

    1. 算法总结及推荐题目 1.1 C++ STL • STL容器: set, map, vector, priority_queue, queue, stack, deque, bitset• STL ...

  7. [转]学习win10的bash使用ssh连接远程服务器

    1. 前言 微软已经在Win10一周年更新预览版中加入了Ubuntu Bash命令支持,相当于一个小型的linux系统,本来连接远程服务器的话,要使用putty啥的,现在可以用这个直接连接,我来讲讲步 ...

  8. .Net 面试总结

    今天去面试了一家公司,做电子商务类的网站的,公司的老板应该比较有能量,可以同时拿下若干项目,技术负责人给提了几个问题: 记不清顺序了 .net 构析函数的作用 泛型的主要作用及应用方面 结构与类的区别 ...

  9. Linux之JDK在线安装及配置

    1.查找java相关得列表  yum -y list java*2.在线安装 yum -y install java-1.6.0-openjdk*3.查看安装目录  ls -l /usr/lib/jv ...

  10. java-2018-01-17计划

    1.一句英语 包括单词 2.一个java版本的设计模式 参考:https://github.com/iluwatar/java-design-patterns 学习了抽象工厂模式 总结:java的RS ...