传送门

A. Two Rival Students

签到。

Code
/*
* Author: heyuhhh
* Created Time: 2019/11/13 22:37:26
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5; int n, x, a, b; void run(){
cin >> n >> x >> a >> b;
if(a > b) swap(a, b);
int tmp = min(a - 1, x);
x -= tmp;
a -= tmp;
tmp = min(n - b, x);
x -= tmp;
b += tmp;
cout << b - a << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int t; cin >> t;
while(t--) run();
return 0;
}

B. Magic Stick

分情况讨论一下即可。

神志不清讨论地很乱

Code
/*
* Author: heyuhhh
* Created Time: 2019/11/13 22:42:05
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5; int a, b; void run(){
cin >> a >> b;
if(a == 1) {
if(b == 1) return pt("YES");
else return pt("NO");
}
if(a >= b) return pt("YES");
if(a > 3) return pt("YES");
if(b <= 3) return pt("YES");
pt("NO");
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int t; cin >> t;
while(t--) run();
return 0;
}

C. Dominated Subarray

题意:

给出\(n\)个数,找到长度最短的区间,满足区间长度大于\(1\)且存在一个数其出现次数严格大于其它数。

思路:

显然最终的答案区间两端点为同一个数,考虑一个这样的区间,如果其不合法,说明存在一个答案更优的区间。

并且若那个数出现次数超过\(2\)次,我们选择一个更小的区间使得这个数只出现\(2\)次,此时有两种情况:一个是合法,那显然答案更优;另一个是不合法,说明答案也可以更优。

就这样归纳一下,发现答案就是两个相同数的最小间隔。

然而我神智不清,写了个线段树

Code
/*
* Author: heyuhhh
* Created Time: 2019/11/13 22:49:57
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5; int n;
int a[N];
int pre[N], last[N];
int maxv[N << 2]; void upd(int o, int l, int r, int p, int v) {
if(p == 5) dbg(l, r);
if(l == r) {
maxv[l] = v;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) upd(o << 1, l, mid, p, v);
else upd(o << 1|1, mid + 1, r, p, v);
maxv[o] = max(maxv[o << 1], maxv[o << 1|1]);
} int query(int o, int l, int r, int L, int R) {
if(L > R) return 0;
if(L <= l && r <= R) {
return maxv[o];
}
int mid = (l + r) >> 1, res = 0;
if(L <= mid) res = query(o << 1, l, mid, L, R);
if(R > mid) res = max(res, query(o << 1|1, mid + 1, r, L, R));
return res;
} void build(int o, int l, int r) {
maxv[o] = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(o << 1, l, mid);
build(o << 1|1, mid + 1, r);
} void run(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i], last[a[i]] = 0;
if(n == 1) return pt(-1);
build(1, 1, n);
for(int i = 1; i <= n; i++) {
pre[i] = last[a[i]];
last[a[i]] = i;
upd(1, 1, n, i, pre[i]);
dbg(i, pre[i]);
}
dbg(query(1, 1, n, 5, 5), pre[5]);
int ans = INF;
for(int i = 1; i <= n; i++) {
if(pre[i]) {
int L = pre[i] + 1, R = i - 1;
dbg(i, L, R);
if(query(1, 1, n, L, R) < L) ans = min(ans, R - L + 3);
}
}
if(ans == INF) ans = -1;
cout << ans << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}

D. Yet Another Monster Killing Problem

题意:

现在有\(n\)只怪,每只怪有力量\(a_i\)。

同时有\(n\)个英雄,每个英雄有\(p_i,s_i\)分别代表力量和耐力。

每一天只能选派一个英雄去打怪兽,每个英雄最多打\(s_i\)只怪,一个英雄能打败一只怪,当且仅当其力量不低于怪兽的力量。

一个英雄可以被选派多次。

问最少需要多少天能打败所有的怪兽。

思路:

  • 考虑\(dp:dp[i]\)表示打败前\(i\)只怪兽最少需要多少天,显然\(dp[i]=min\{dp[j]+1\}\)
  • \(j\)满足存在一个英雄,能从\(j+1\)打到\(i\),显然这个\(j\)的位置具有单调性。
  • 发现\(dp\)值也是单调不降的,那么我们就可以找一个最远的\(j\)进行转移,二分即可。
  • 二分的话,可以对英雄的耐力维护一个后缀最大值,即\(maxv[s]\)表示耐力\(\geq s\)的英雄中,最大的力量为多少;同时维护怪兽力量的区间最大值,这里\(rmq\)维护即可。两个判断一下就行。

神志不清写了一年

Code
/*
* Author: heyuhhh
* Created Time: 2019/11/13 23:47:28
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5; int n, m;
int a[N];
struct node{
int s, p;
bool operator < (const node &A) const {
return s < A.s;
}
}b[N];
int f[N][22];
int lg[N];
void init() {
lg[2] = 1;
for(int i = 3; i < N; i++) lg[i] = lg[i >> 1] + 1;
}
int ask(int l, int r) {
int k = lg[r - l + 1];
return max(f[l][k], f[r - (1 << k) + 1][k]);
}
int dp[N], maxv[N];
bool chk(int l, int r) {
int mx = ask(l, r);
int i = lower_bound(b + 1, b + m + 1, node{r - l + 1, 0}) - b;
return maxv[b[i].s] >= mx;
}
int get(int x) {
int l = 1, r = x + 1, mid;
while(l < r) {
mid = (l + r) >> 1;
if(chk(mid, x)) r = mid;
else l = mid + 1;
}
return r;
}
void run(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i], f[i][0] = a[i];
for(int i = 1; i <= 20; i++) {
for(int j = 1; j + (1 << (i - 1)) <= n; j++) {
f[j][i] = max(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]);
}
}
cin >> m;
for(int i = 1; i <= m; i++) cin >> b[i].p >> b[i].s;
sort(b + 1, b + m + 1);
b[m + 1].s = 0;
for(int i = m; i >= 1; i--) {
maxv[b[i].s] = max(maxv[b[i + 1].s], b[i].p);
}
if(maxv[b[1].s] < ask(1, n)) return pt(-1);
dp[0] = 0;
for(int i = 1; i <= n; i++) {
int p = get(i) - 1;
dp[i] = dp[p] + 1;
}
cout << dp[n] << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
init();
int T; cin >> T;
while(T--) run();
return 0;
}

E. The Contest

题意:

给出三个集合,每个集合里面装了一些数,这些数的并集为\(1\)~\(n\)的排列。

现在可以移动任意一个数从一个集合到另外一个集合。

问最少的移动次数使得\(1\)集合中为一个前缀\(1,\cdots,k\),然后\(2\)集合中\(k+1,\cdots,p\),\(3\)集合中\(p+1,\cdots,n\)。(可以有集合为空集)。

思路:

  • 考虑枚举\(1\)集合中装的前缀的长度,然后将其余的所有数我们先移到\(3\)集合中,并且给这些数打上标记,表示删除这些数不消耗额外的次数。
  • 之后我们要操作一些数,使得\(3\)集合中的数为一个后缀。
  • 显然我们对\(3\)集合的操作是删掉前面的一些数,然后填补后面的空格。假设\(3\)集合中的数为\(p\)~\(n\),那么我们用\(pre[i]\)表示\(3\)集合中原来有的数的前缀,\(suf[i]\)表示后缀空格的数量。那么显然我们枚举\(i,i\geq p\),求出\(min\{pre[i]-pre[p-1]+suf[i+1]\}\)即可。
  • 显然\(p\)随着枚举\(1\)集合前缀个数时在不断增大,那么直接维护后缀\(pre[i]+suf[i+1]\)的最小值即可。

时间复杂度\(O(n)\)。也可以\(dp\)来做,\(dp[i][j]\)表示第\(i\)个数在第\(j\)个集合的最小操作次数。因为分布连续,直接分情况考虑即可。

然而神志不清,想了好久都没想清楚

Code
/*
* Author: heyuhhh
* Created Time: 2019/11/14 9:29:05
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
//#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5; int k1, k2, k3, n;
int a[N], b[N], c[N];
int suf[N], pre[N], sum[N], Min[N];
int f[N]; void run(){
n = k1 + k2 + k3;
memset(f, 0, sizeof(f));
for(int i = 1; i <= k1; i++) cin >> a[i];
for(int i = 1; i <= k2; i++) cin >> b[i];
for(int i = 1; i <= k3; i++) cin >> c[i];
int tot = 0;
int i = 1, j = 1;
for(int i = 1; i <= k1; i++) f[a[i]] = 2;
for(int i = 1; i <= k3; i++) f[c[i]] = 1;
for(int i = 1; i <= n; i++) {
pre[i] = pre[i - 1] + (f[i] == 1);
}
for(int i = n; i >= 1; i--) {
suf[i] = suf[i + 1] + (f[i] == 0);
}
for(int i = n; i >= 0; i--) {
if(i == n) Min[i] = pre[i];
else Min[i] = min(Min[i + 1], pre[i] + suf[i + 1]);
}
for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + (f[i] == 2);
int ans = INF;
for(int i = 0; i <= n; i++) {
dbg(i, pre[i], suf[i], Min[i] - pre[i]);
ans = min(ans, i - 2 * sum[i] + sum[n] - pre[i] + Min[i]);
}
cout << ans << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> k1 >> k2 >> k3) run();
return 0;
}

F. Make Them Similar

题意:

给出\(n,n\leq 100\)个数,现在定义两个数相似为其二进制\(1\)的个数相同。

现在问能否找到一个数\(x\),使得这\(n\)个数都异或上\(x\),并且最终都相似。

\(a_i\leq 2^{30}-1\)。

思路:

  • 显然我们要从二进制的每一位来考虑,但是直接来考虑又显然不行。
  • 注意到二进制位不超过\(30\),那么可以考虑\(meet\ in\ middle\)的方法:即折半处理,预处理出一边,然后枚举这一边。
  • 预处理一边后随便用个\(map\)或哈希一下存储即可。

感觉这个比前几个稍微还简单点?

可能是因为我之前神志不清hhh

Code
/*
* Author: heyuhhh
* Created Time: 2019/11/14 15:21:26
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 100 + 5; int n;
int a[N]; unordered_map<string, int> mp;
string trans(int x) {
string res = "";
if(x > 9) {
res += ((x / 10) + '0');
res += ((x % 10) + '0');
} else res += (x + '0');
return res;
}
void run(){
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 0; i < 1 << 15; i++) {
for(int k = 0; k <= 30; k++) {
int ok = 1;
for(int j = 1; j <= n; j++) {
int x = (a[j] >> 15) ^ i;
if(__builtin_popcount(x) > k) ok = 0;
}
if(ok) {
string tmp = "";
for(int j = 1; j <= n; j++) {
int x = (a[j] >> 15) ^ i;
tmp += trans(k - __builtin_popcount(x));
}
if(mp.find(tmp) == mp.end())
mp[tmp] = i;
}
}
}
for(int i = 0; i < 1 << 15; i++) {
string tmp = "";
for(int j = 1; j <= n; j++) {
int x = ((a[j] >> 15) << 15) ^ a[j];
x ^= i;
tmp += trans(__builtin_popcount(x));
}
if(mp.find(tmp) != mp.end()) {
int ans = (mp[tmp] << 15) + i;
cout << ans << '\n';
return;
}
}
cout << -1 << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}

Educational Codeforces Round 76 (Rated for Div. 2)的更多相关文章

  1. Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest

    Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest(dp+线段树) 题目链接 题意: 给定3个人互不相同的多个数字,可以 ...

  2. Educational Codeforces Round 76 (Rated for Div. 2)E(dp||贪心||题解写法)

    题:https://codeforces.com/contest/1257/problem/E 题意:给定3个数组,可行操作:每个数都可以跳到另外俩个数组中去,实行多步操作后使三个数组拼接起来形成升序 ...

  3. Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest dp

    E. The Contest A team of three programmers is going to play a contest. The contest consists of

  4. Educational Codeforces Round 76 (Rated for Div. 2) D. Yet Another Monster Killing Problem 贪心

    D. Yet Another Monster Killing Problem You play a computer game. In this game, you lead a party of

  5. Educational Codeforces Round 76 (Rated for Div. 2) C. Dominated Subarray 水题

    C. Dominated Subarray Let's call an array

  6. Educational Codeforces Round 76 (Rated for Div. 2) B. Magic Stick 水题

    B. Magic Stick Recently Petya walked in the forest and found a magic stick. Since Petya really likes ...

  7. Educational Codeforces Round 76 (Rated for Div. 2) A. Two Rival Students 水题

    A. Two Rival Students There are

  8. Educational Codeforces Round 76 (Rated for Div. 2) D题

    题意: 给你n个关卡,每个关卡有一个怪物,怪物的攻击力为a[i],你有n个英雄,每个英雄有一个攻击力,和疲劳值,只要英雄的攻击力比怪物的高就算打过了,同时疲劳减一,一天只能出战一个英雄,一个英雄可以打 ...

  9. Educational Codeforces Round 76 (Rated for Div. 2) D

    D题 原题链接 题意:就是给你n个怪兽有一个属性(攻击力),m个英雄,每个英雄有两种属性(分别为攻击力,和可攻击次数),当安排最好的情况下,最少的天数(每选择一个英雄出战就是一天) 思路:因为怪兽是不 ...

随机推荐

  1. weed3-2.1.开始纯java使用

    Weed3 一个微型ORM框架(只有0.1Mb哦) 源码:https://github.com/noear/weed3 源码:https://gitee.com/noear/weed3 纯java使用 ...

  2. How to: Use Both Entity Framework and XPO in a Single Application 如何:在单个应用程序中同时使用实体框架和 XPO

    This topic demonstrates how to create a simple XAF application that uses both the Entity Framework ( ...

  3. Git实战指南----跟着haibiscuit学Git(第四篇)

    笔名:  haibiscuit 博客园: https://www.cnblogs.com/haibiscuit/ Git地址: https://github.com/haibiscuit?tab=re ...

  4. Axure导出的原型无法在谷歌浏览器浏览

    1.下载crx后缀的文件. 2.修改crx后缀名为rar的压缩文件 3.解压刚才的rar文件 4.打开谷歌浏览器右上角的三个点 更多工具==>扩展程序 选择刚才的解压文件夹. 上面的图表示安装成 ...

  5. C lang: Pointer

    Ax_Terminology xa_pointer pointer is the address used to store the variable;A variable (or data obje ...

  6. LeetCode刷题191127

    数据库: 1179 部门表 Department: +---------------+---------+| Column Name | Type |+---------------+-------- ...

  7. 浅谈——MySQL存储引擎

    博文大纲: 一.MyISAM存储引擎: 二.InnoDB存储引擎: 三.Memory存储引擎特点: 四.如何选择合适的存储引擎? 前言 数据库存储引擎是数据库底层软件组件,数据库管理系统(DBMS)使 ...

  8. Linux基础命令---ntpstat显示时间服务器同步

    ntpstat ntpstat指令用于显示本机上一次和服务器同步时间的情况. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora.   1.语法 ntpstat   2 ...

  9. layui多个时间选择器出现闪退问题

    1.出现问题的代码 laydate.render({ elem: '#startDate' // }); laydate.render({ elem: '#endDate' // }); laydat ...

  10. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3

    A,有多个线段,求一条最短的线段长度,能过覆盖到所又线段,例如(2,4)和(5,6) 那么我们需要4 5连起来,长度为1,例如(2,10)(3,11),用(3,10) 思路:我们想一下如果题目说的是最 ...