传送门

A. XORinacci

签到。

Code
/*
* Author: heyuhhh
* Created Time: 2020/2/26 9:26:33
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#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 f[3];
int a, b, n; void run(){
cin >> a >> b >> n;
f[0] = a, f[1] = b;
f[2] = a ^ b;
n %= 3;
cout << f[n] << '\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. Uniqueness

题意:

给出\(n,n\leq 2000\)个数,现在可以至多删除一段区间\([l,r]\)。最后要使得剩下的数互不相同。问最终删除区间的最小长度为多少。

思路:

枚举左、右端点,用一个\(set\)来维护剩下的元素即可。

时间复杂度\(O(n^2logn)\)。

Code
/*
* Author: heyuhhh
* Created Time: 2020/2/26 9:34:06
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#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 = 2000 + 5; int n;
int a[N]; void run(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
set <int> s;
int ans = n;
for(int l = 0; l <= n; l++) {
if(s.count(a[l])) break;
s.insert(a[l]);
ans = min(ans, n - l);
set <int> t;
for(int r = n; r > l; r--) {
if(s.count(a[r]) || t.count(a[r])) break;
t.insert(a[r]);
ans = min(ans, r - l - 1);
}
}
cout << ans << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}

C. Magic Grid

题意:

现在要构造一个\(n\cdot n\)的矩阵,矩阵里面的数互不相同,取值为\([0,n^2-1]\),并且使得矩阵中行、列异或值都相同。

思路:

归纳一下,直接将整个矩阵按\(k\)分块,分成多个\(4\cdot 4\)的小矩阵构造就行。

正确性因为所有的数都加上\(2^x\)过后,最后的异或值不会发生变化。

代码如下:

Code
/*
* Author: heyuhhh
* Created Time: 2020/2/26 11:02:11
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#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 = 1000 + 5; int n;
int a[N][N]; void run() {
int k = n / 4;
int now = 0;
for(int i = 1; i <= k; i++) {
for(int j = 1; j <= k; j++) {
for(int x = (i - 1) * 4 + 1; x <= i * 4; x++) {
for(int y = (j - 1) * 4 + 1; y <= j * 4; y++) {
a[x][y] = now++;
}
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
cout << a[i][j] << " \n"[j == n];
}
}
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}

D. Restore Permutation

直接从后往前构造即可,利用树状数组+二分查询来确定一个位置的值,时间复杂度\(O(nlog^2n)\)。

代码如下:

Code
/*
* Author: heyuhhh
* Created Time: 2020/2/26 16:34:24
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#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;
int a[N];
ll s[N]; struct BIT {
ll c[N];
int lowbit(int x) {return x & (-x);}
void add(int x, int v) {
for(; x < N; x += lowbit(x)) c[x] += v;
}
ll query(int x) {
ll res = 0;
for(; x; x -= lowbit(x)) res += c[x];
return res;
}
}bit; void run(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> s[i];
for(int i = 1; i <= n; i++) bit.add(i, i);
for(int i = n; i >= 1; i--) {
int l = 1, r = n + 1, mid;
while(l < r) {
mid = (l + r) >> 1;
if(bit.query(mid) > s[i]) r = mid;
else l = mid + 1;
}
a[i] = l;
bit.add(a[i], -a[i]);
}
for(int i = 1; i <= n; i++) cout << a[i] << " \n"[i == n];
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}

E. Let Them Slide

题意:

有一个\(n\cdot w,n,w\leq 10^6\)的表,现在有\(n\)个数组,每个数组中元素的取值范围为\([-10^9,10^9]\),所有数组的长度之和不超过\(10^6\)。

每一个数组可以在表内左右移动。

问最后对于每一列,其和的最大值为多少。

思路:

  • 对每一个数组单独考虑其贡献:容易发现一个数组对列的贡献为\(1,2,\cdots,max,\cdots,max,max-1,\cdots,2,1\)的形式。
  • 形象点来说,一个数组的贡献一开始为一个从\(1\)开始,有着最大宽度的滑动窗口;最后窗口宽度会回到\(1\)。中间有一段对列的贡献始终相同。
  • 那么我们中间的那一段可以直接利用差分来处理,而前面部分和后面部分我们直接暴力计算贡献就行。用\(set\)的话好写一点,时间复杂度为\(O(len\cdot log_{len})\)。
  • 注意一点细节:因为可能窗口中的最大值为负数,在某些位置,我们可以让这一列为空,那么最后的取值就是\(0\)了。对于这一点的处理可以找一下关系:设当前数组的长度为\(k\),那么\(r=w-k\),\([1,r],[w-k+1,w]\)这段可以取\(0\);我们最后窗口的上界为\(min(k,w-k+1)\)。
    • 显然当\(2k\leq w\)时,所有位置均可取\(0\);
    • 当\(2k>w\)即上界\(max=k\)时,此时\(r<k\),那么\([1,r]、[w-k+1,w]\)这两段区间我们暴力计算的时候可以直接计算。

最终总的时间复杂度为\(O(nlogn)\),这里的\(n\)为数组总长度。

细节见代码:

Code
/*
* Author: heyuhhh
* Created Time: 2020/2/26 17:04:19
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.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 = 1e6 + 5; int n, w;
int a[N];
ll ans[N], sum[N]; void run(){
cin >> n >> w;
multiset <int> S;
for(int i = 1; i <= n; i++) {
int k; cin >> k;
for(int j = 1; j <= k; j++) cin >> a[j];
S.clear();
int Max = min(k, w - k + 1), r = w - k;
if(2 * k <= w) {
for(int j = 1; j <= k; j++) if(a[j] < 0) a[j] = 0;
}
for(int j = 1; j <= w; j++) {
if(j <= Max) {
S.insert(a[j]);
} else if(j <= min(k, w - Max + 1)) {
S.insert(a[j]);
auto it = S.lower_bound(a[j - Max]);
assert(it != S.end());
S.erase(it);
} else if(j > w - Max + 1) {
auto it = S.lower_bound(a[k - Max + j - (w - Max + 1)]);
assert(it != S.end());
S.erase(it);
} else {
int st = j;
int ed = w - Max + 1 + 1;
auto it = S.end(); it--;
int now = *it;
sum[st] += now, sum[ed] -= now;
j = w - Max + 1;
continue;
}
auto it = S.end(); it--;
int now = *it;
if(j <= r || j >= w - r + 1) now = max(0, now);
ans[j] += now;
}
assert(S.size() == 1);
}
for(int i = 1; i <= w; i++) {
sum[i] += sum[i - 1];
ans[i] += sum[i];
}
for(int i = 1; i <= w; i++) {
cout << ans[i] << " \n"[i == w];
}
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}

F. Bits And Pieces

题意:

给出序列\(a_{1,2\cdots,n},n\leq 10^6\)。

现在要找最大的\(a_i|(a_j\& a_k)\),其中\((i,j,k)\)满足\(i<j<k\)。

思路:

  • 显然我们可以枚举\(a_i\),那么问题就转换为如何快速找\(a_j\& a_k\)。
  • 暴力的方法就是从高到低枚举二进制每一位,然后用各种方法乱搞。
  • 因为最后要使得结果最大,我们二进制从高到底枚举时肯定是贪心来考虑的:即如果有两个数他们的与在这一位为\(1\),那么最后的答案中一定有这一位。
  • 那么我们逐位考虑,并且考虑是否有两个在右边的数他们与的结果为当前答案的超集即可,有的话答案直接加上这一位。
  • 那么可以用\(sos\ dp\)处理超集的信息,并且维护在最右端的两个位置,之后贪心来处理即可。

稍微来说一下这个\(sos\ dp\),我们定义\(dp[i][mask]\)为状态为\(mask\)时,处理了二进制后面\(i\)位的超集信息后,当前最右端的两个位置。那么转移时枚举第\(i+1\)位,若这一位为\(1\),那么\(dp[i][mask]\rightarrow dp[i+1][mask-(1<<(i+1))],dp[i+1][mask]\)进行转移即可。

代码中滚动掉了一维。

细节见代码:

Code
/*
* Author: heyuhhh
* Created Time: 2020/2/27 10:51:39
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#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 = 2e6 + 5; int n;
int a[N];
pii dp[N]; void add(int x, int id) {
if(dp[x].fi == -1) {
dp[x].fi = id;
} else if(dp[x].se == -1) {
if(dp[x].fi == id) return;
dp[x].se = id;
if(dp[x].fi < dp[x].se) swap(dp[x].fi, dp[x].se);
} else if(dp[x].fi < id) {
dp[x].se = dp[x].fi;
dp[x].fi = id;
} else if(dp[x].se < id) {
if(dp[x].fi == id) return;
dp[x].se = id;
}
} void merge(int x1, int x2) {
add(x1, dp[x2].fi);
add(x1, dp[x2].se);
} void run() {
memset(dp, -1, sizeof(dp));
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
add(a[i], i);
}
for(int i = 0; i < 21; i++) {
for(int j = 0; j < N; j++) if(j >> i & 1) {
merge(j ^ (1 << i), j);
}
}
int ans = 0;
for(int i = 1; i <= n - 2; i++) {
int lim = (1 << 21) - 1;
int cur = a[i] ^ lim, res = 0;
for(int j = 20; j >= 0; j--) if(cur >> j & 1) {
if(dp[res ^ (1 << j)].se > i) {
res ^= (1 << j);
}
}
ans = max(ans, res | a[i]);
}
cout << ans << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}

Manthan, Codefest 19(Div. 1 + Div. 2)的更多相关文章

  1. Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-D. Restore Permutation-构造+树状数组

    Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-D. Restore Permutation-构造+树状数组 [Pro ...

  2. Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-C. Magic Grid-构造

    Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-C. Magic Grid-构造 [Problem Descripti ...

  3. Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-E. Let Them Slide-思维+数据结构

    Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-E. Let Them Slide-思维+数据结构 [Problem ...

  4. 云端搭建Linux学习环境 链接https://edu.aliyun.com/article/19 (阿里云ECS服务器 )课堂

    云端搭建Linux学习环境 链接https://edu.aliyun.com/article/19 1. 开通云服务器 2 1.包年包月   按量付费(适合测试数据的时候) 2 2.地域   服务器数 ...

  5. Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)D(树状数组)

    //树状数组中数组的特性,有更巧妙的方法.//我们知道在树状数组中,对于数组tree[i],它所维护的区间为[i−lowbit(i)+1,i]//所以对于tree[2^i],它所维护的区间就为[1,2 ...

  6. RMQ+差分处理(Let Them Slide)Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)

    题意:https://codeforc.es/contest/1208/problem/E 现有n行w列的墙,每行有一排连续方块,一排方块可以左右连续滑动,且每个方块都有一个价值,第i 列的价值定义为 ...

  7. 线段树维护最后一个0的位置(Restore Permutation)Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)

    题意:https://codeforc.es/contest/1208/problem/D 给你长度为n的序列,s[i]的值为p[1]到p[i-1]中比p[i]小的数的和,让你求出p序列. 思路: 首 ...

  8. Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)E(多重集维护)

    #define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;long long ans[1000007]; ...

  9. Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)B(SET)

    #define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;int a[2007];set<int& ...

随机推荐

  1. 如何在Windows中使用Eclipse访问虚拟机Linux系统中的hadoop(伪分布式)

    因为计算机配置过低,在虚拟机里几乎无法使用Eclipse,效率极低! 所以现在尝试使用Windows下Eclipse操作虚拟机中Hadoop,步骤如下: 开发环境:Hadoop2.7.1,Ubuntu ...

  2. python函数1_参数,返回值和嵌套

    函数 将重复的代码,封装到函数,只要使用直接找函数 函数可以增强代码的模块化和提高代码的重复利用率 函数的定义和调用 格式 def 函数名([参数,参数...]): 函数体 定义函数 import r ...

  3. hexo 搭建静态博客 + Next 主题配置

    参考手册 HEXO:https://hexo.io/zh-cn/ NEXT:http://theme-next.iissnan.com/ 安装hexo npm install hexo-cli -g ...

  4. SVM的优缺点

    优点 可用于线性/非线性分类,也可以用于回归,泛化错误率低,也就是说具有良好的学习能力,且学到的结果具有很好的推广性. 可以解决小样本情况下的机器学习问题,可以解决高维问题,可以避免神经网络结构选择和 ...

  5. Linux新手常用命令

    Linux下有时候需要转换到管理员权限 su root   然后输入密码  或者直接  su ---------------------------------------- 但可能存在鉴定错误的异常 ...

  6. 使用vASA842配置ASDM645

    准备:使用VMware打开vASA842.ova文件,将第一个网络适配器桥接到一个vmnet接口,我这里是vmnet3,网段是10.0.0.0/24,网关是10.0.0.1/24 1.打开vASA84 ...

  7. WLC-Download 3-party CA to WLC

    一.基础准备 为了创建和导入第三方SSL-certificate你需要做如下准备:1.一个WLC(随着版本的不同,可能需要准备的也不同)这里以7.0.98版本为例.2.一个外部的证书颁发机构(Cert ...

  8. 【转】uWSGI+django+nginx的工作原理流程与部署历程

    一.前言献给和我一样懵懂中不断汲取知识,进步的人们. 霓虹闪烁,但人们真正需要的,只是一个可以照亮前路的烛光 二.必要的前提 2.1 准备知识 1.django 一个基于python的开源web框架, ...

  9. Linux kali安装chromium

    打开终端,输入以下命令 apt-get install chromium chromium-l10n

  10. Linux中制作静态库

    静态库生成: 1.第一步:生成.o文件 2.第二步:将所有.o文件打包 ar src  libMyTest.a  *.o 生成出libMyTest.a 3.使用: 第一种:gcc  main.c    ...