传送门

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. Python中通过csv的writerow输出的内容有多余的空行两种方法

    第一种方法 如下生成的csv文件会有多个空行 import csv #python2可以用file替代open with open("test.csv","w" ...

  2. springboot使用hibernate validator

    前言 在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动 方法内代码显得冗长 每次要看哪些参 ...

  3. WebSocket断开原因、心跳机制防止自动断开连接

    1.断开原因 WebSocket断开的原因有很多,最好在WebSocket断开时,将错误打印出来. ws.onclose = function (e) { console.log('websocket ...

  4. SVN异常,Previous operation has not finished; run 'cleanup' if it was interrupted

    SVN在提交.更新.cleanup时报错:Problem running logsvn: Failed to run the WC DB work queue associated with 'D:\ ...

  5. Viewpager+Fragment 跳转Activity报错android.os.TransactionTooLargeException: data parcel size xxxxx bytes

    Viewpager + Fragment 跳转Activity报错android.os.TransactionTooLargeException: data parcel size xxxxx byt ...

  6. Where is the kernel documentation?; Ubuntu 上如何安装 linux 内核文档;fedora 上如何安装linux内核文档?

    有时候,linux内核文档对我们很重要,我们可以在linux系统中安装,并及时查看: 参考链接:https://askubuntu.com/questions/841043/where-is-the- ...

  7. PS各种行业文件创建

    ps可以运用于:印刷.喷绘.网络等行业. 印刷 创建的印刷文件需要修改为毫米为单位,分辨率300以上,CMYK颜色格式: 16开的尺寸为:210*285mm:但在印刷之后,剪裁需要留出出血位,上下左右 ...

  8. git 分布式控制版本管理器(上)

    git的作用: 1.更方便的存储版本 2.恢复之前的版本 3.更方便的对比 4.协同合作 下载地址git官网: https://git-scm.com/ 可自选自己电脑的操作系统 安装: 一路next ...

  9. 关于在maven项目中配置文件资源导出问题

    标准的Maven项目都会有一个resources目录来存放我们所有的资源配置文件,但是我们往往在项目中不仅仅会把所有的资源配置文件都放在resources中,同时我们也有可能放在项目中的其他位置,那么 ...

  10. java 主动信任证书

    java 主动信任证书 SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mid.toCharArray() ...