传送门

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. Serverless 实战——使用 Rendertron 搭建 Headless Chrome 渲染解决方案

    为什么需要 Rendertron? 传统的 Web 页面,通常是服务端渲染的,而随着 SPA(Single-Page Application) 尤其是 React.Vue.Angular 为代表的前端 ...

  2. C#/.Net开发入门篇(2)——第一个控制台应用程序

    相信看了上一篇文章的小伙伴已经安装好自己的开发工具了VS了,这一篇文章就教大家怎么创建第一个应用程序. 下面大家跟着我的操作一起来创建自己的第一个应用程序吧 一.打开VS工具点击左上角的文件→新建→项 ...

  3. C#后台架构师成长之路-进阶体系篇章大纲

    这些知识体系概念和应用如果不了解,怎么修炼你的内功..... 1.数据类型的理解,比如bool,byte,short,ushort,int,uint,long,ulong,float,double,s ...

  4. redis cluster集群动态伸缩--删除主从节点

    目标:从集群中剔除一组主从(5007,5008) 经过上一节增加5007,5008主从服务节点后,目前集群的情况是这样的: b3363a81c3c59d57143cd3323481259c044e66 ...

  5. javascript随机数发现的一个parseInt函数的问题

    前几天想伪造一些数据,用到了随机数,没有自己写,便在网上找了一下,找到了这篇文章:https://www.cnblogs.com/starof/p/4988516.html .之后测试了一下,发现了一 ...

  6. C# 类库项目 无法创建 “资源字典” 文件

    1.接触WPF有两个月时间了,准备自己写一个样式库,在vs新建 类库项目后无法创建资源字典. 2.解决办法: 打开项目工程文件      (  project.csproj) 在 <Proper ...

  7. shell 脚本里的$(( ))、$( )、``与${ }的区别

    shell  脚本里的命令执行 1. 在bash中,$( )与` `(反引号)都是用来作命令替换的. 命令替换与变量替换差不多,都是用来重组命令行的,先完成引号里的命令行,然后将其结果替换出来,再重组 ...

  8. C# 中代码执行 ping 操作

    在代码中可以通过调用 System.Net.NetworkInformation 命名控件下的 Ping 类的 Send() 方法来实现,代码如下: var ping = new System.Net ...

  9. 使用admin的步骤、必知必会13条、单表的双下划线、外键的操作、多对多的操作:

    MVC M: model 模型 与数据库交互 V: view 视图 HTML C:controller 控制器 流程 和 业务逻辑 MTV M:model ORM T:template 模板 HTML ...

  10. 多对多表结构的设计ManyToManyField(不会生成某一列、生成一张表):

    示例: 脚本: from django.db import models# Create your models here. class Publisher(models.Model): name = ...