Shuffle Hashing

\[Time Limit: 2 s\quad Memory Limit: 256 MB
\]

处理出 \(s_1\) 中各个字符出现的次数,然后双指针维护 \(s_2\) 中每一段长度为 \(len(s_1)\) 的串中字符出现的次数,如果存在某一段和 \(s_1\) 的字符次数相同,则是答案。

view
#include <map>
#include <set>
#include <list>
#include <tuple>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pb push_back
#define pii pair<int, int>
#define INOPEN freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout) typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 1e2 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std; int n, m, k;
int cas, tol, T; int cnt[26];
char s1[maxn], s2[maxn]; bool ok() {
for(int i=0; i<26; i++) if(cnt[i]) return 0;
return 1;
} int main() {
scanf("%d", &T);
while(T--) {
mes(cnt, 0);
scanf("%s%s", s1+1, s2+1);
n = strlen(s1+1), m = strlen(s2+1);
if(n>m) {
puts("NO");
continue;
}
for(int i=1; i<=n; i++) cnt[s1[i]-'a']++;
for(int i=1; i<=n; i++) cnt[s2[i]-'a']--;
bool f = 0;
for(int i=n; i<=m; i++) {
if(ok()) f = 1;
if(i==m) break;
cnt[s2[i+1]-'a']--;
cnt[s2[i-n+1]-'a']++;
}
puts(f ? "YES" : "NO");
}
return 0;
}

A and B

\[Time Limit: 1 s\quad Memory Limit: 256 MB
\]

说出来你可能不信,强行 \(oeis\) 过了。

view
#include <map>
#include <set>
#include <list>
#include <tuple>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pb push_back
#define pii pair<int, int>
#define INOPEN freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout) typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 1e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std; ll n, m;
int cas, tol, T; int main() {
scanf("%d", &T);
while(T--) {
ll a, b;
scanf("%lld%lld", &a, &b);
n = abs(a-b);
ll k=0;
for(; ; k++) {
if(k*(k+1)/2 <= n && n<(k+1)*(k+2)/2) break;
}
ll tk = k*(k+1)/2;
ll ans;
if(n == tk) ans = k;
else {
if(k%2 == 1) {
if((n-tk)%2==1) ans = k+2;
else ans = k+1;
} else {
if((n-tk)%2==1) ans = k+1;
else ans = k+3;
}
}
printf("%lld\n", ans);
}
return 0;
}

Berry Jam

\[Time Limit: 2 s\quad Memory Limit: 256 MB
\]

预处理后半段中 \(1\) 比 \(2\) 多吃 \(x\) 瓶所需要的最少步数,然后枚举前半段中吃到第 \(i\) 瓶处,\(1\) 还需要比 \(2\) 多吃 \(y\) 瓶,然后在后半段预处理中找答案。

view
#include <map>
#include <set>
#include <list>
#include <tuple>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pb push_back
#define pii pair<int, int>
#define INOPEN freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout) typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 2e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std; int n, m;
int cas, tol, T; int a[maxn];
unordered_map<int, int> mp; int main() {
scanf("%d", &T);
while(T--) {
mp.clear();
scanf("%d", &n);
int y = 0;
for(int i=1; i<=n+n; i++) {
scanf("%d", &a[i]);
y += a[i]==1 ? 1:-1;
}
if(y == 0) {
printf("0\n");
continue;
}
mp[0] = 0;
for(int i=n+1, x=0; i<=n+n; i++) {
x += a[i]==1 ? 1:-1;
if(!mp.count(x)) mp[x] = i-n;
}
// for(auto t : mp) printf("%d %d\n", t.fi, t.se);
int ans = inf;
for(int i=n; i>=0; i--) {
if(mp.count(y))
ans = min(ans, n-i+mp[y]);
if(!i) break;
y -= a[i]==1 ? 1:-1;
}
printf("%d\n", ans);
}
return 0;
}

Segment Tree

\[Time Limit: 2 s\quad Memory Limit: 256 MB
\]

把线段先按 \(l\) 在按 \(r\) 排序,然后枚举第 \(i\) 条线段,判断它可以和哪些线段连边。

可以发现,在枚举第 \(i\) 条线段时,前 \(i-1\) 条线段的 \(l\) 一定都是比我的 \(l\) 小的,所以我其实是需要找到前 \(i-1\) 条线段中,找到所有满足 \(p[i].l \leq p[j].r \leq p[i].r\) 的所有 \(j\)。

这一段区间是连续的,所以我们可以维护一个 \(set\) 的 \(pair\),用来存放前 \(i-1\) 条边的 \(r\) 位置和编号。然后用 \(set\) 的二分来快速找到所有的 \(j\)。

又因为想要形成一棵树,这也就意味着最多只会添加 \(n-1\) 条边,那么整体复杂度就不会太大。

view
#include <map>
#include <set>
#include <list>
#include <tuple>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define l first
#define r second
#define pb push_back
#define pii pair<int, int>
#define INOPEN freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout) typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 5e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std; int n, m;
int cas, tol, T; int fa[maxn];
pii p[maxn];
set<pii> st; int find(int x) {
return fa[x]==x ? x : fa[x]=find(fa[x]);
} bool bind(int x, int y) {
x = find(x), y = find(y);
if(x == y) return 0;
fa[x] = y;
return 1;
} int main() {
scanf("%d", &n);
for(int i=1; i<=n; i++) {
scanf("%d%d", &p[i].l, &p[i].r);
fa[i] = i;
}
sort(p+1, p+1+n);
st.clear();
int sz = 0, f = 1;
for(int i=1; i<=n; i++) {
auto pos = st.lower_bound({p[i].l, -1});
for(auto j = pos; j!=st.end(); j++) {
if((*j).l > p[i].r) break;
sz++;
if(sz==n || !bind(i, (*j).r)) {
f = 0;
break;
}
}
if(!f) break;
st.insert({p[i].r, i});
}
set<int> ans;
for(int i=1; i<=n; i++) ans.insert(find(i));
puts(ans.size()==1&&f ? "YES" : "NO");
return 0;
}

Tests for problem D

\[Time Limit: 2 s\quad Memory Limit: 256 MB
\]

考虑模拟一下第一个样例,它的放置规则是先把 \(1\) 看成整棵树的根,那么可以先确定 \(p[1].r = 2*n\),然后它有两个直接儿子,所以我需要在 \(r\) 前面留两个空给这两个儿子放 \(r\) 用,现在已经没有直接儿子了,为了防止新的交叉出现,接下来我就放上自己的 \(l\),对于下面的儿子也是同理,可以递归处理。

然后就是儿子的 \(l\) 问题了,由于 \(1\) 的各个儿子不能有交叉部分,也就意味着这些得是重合起来的,所以一开始放在最后的 \(r\),其对应的 \(l\) 就应该尽量小,所以我越早放在后面的儿子,应该越晚去 \(dfs\) 确定其 \(l\)。

为了防止数字重复被用到,可以用一个 \(set\) 来维护还可以用的数字。

view
#include <map>
#include <set>
#include <list>
#include <tuple>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define l first
#define r second
#define pb push_back
#define pii pair<int, int>
#define INOPEN freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout) typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 5e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std; int n, m;
int cas, tol, T; set<int> st;
pii p[maxn];
vector<int> g[maxn]; void dfs(int u, int fa) {
int len = g[u].size();
for(int i=0; i<len; i++) if(g[u][i] != fa) {
p[g[u][i]].r = *(--st.end());
st.erase((--st.end()));
}
p[u].l = *(--st.end());
st.erase((--st.end()));
// printf("p%d .l = %d .r = %d\n", u, p[u].l, p[u].r);
for(int i=len-1; ~i; i--) if(g[u][i] != fa) {
dfs(g[u][i], u);
}
} int main() {
scanf("%d", &n);
for(int i=2, u, v; i<=n; i++) {
scanf("%d%d", &u, &v);
g[u].pb(v), g[v].pb(u);
}
p[1].r = 2*n;
for(int i=1; i<2*n; i++) st.insert(i);
dfs(1, 1);
for(int i=1; i<=n; i++) printf("%d %d\n", p[i].l, p[i].r);
return 0;
}
/*
3
1 2
1 3
*/

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

  1. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

  2. Educational Codeforces Round 65 (Rated for Div. 2)题解

    Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...

  3. Educational Codeforces Round 64 (Rated for Div. 2)题解

    Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...

  4. Educational Codeforces Round 60 (Rated for Div. 2) 题解

    Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...

  5. Educational Codeforces Round 58 (Rated for Div. 2) 题解

    Educational Codeforces Round 58 (Rated for Div. 2)  题目总链接:https://codeforces.com/contest/1101 A. Min ...

  6. Educational Codeforces Round 78 (Rated for Div. 2) D. Segment Tree

    链接: https://codeforces.com/contest/1278/problem/D 题意: As the name of the task implies, you are asked ...

  7. Educational Codeforces Round 78 (Rated for Div. 2) C. Berry Jam

    链接: https://codeforces.com/contest/1278/problem/C 题意: Karlsson has recently discovered a huge stock ...

  8. Educational Codeforces Round 78 (Rated for Div. 2) B. A and B

    链接: https://codeforces.com/contest/1278/problem/B 题意: You are given two integers a and b. You can pe ...

  9. Educational Codeforces Round 78 (Rated for Div. 2) A. Shuffle Hashing

    链接: https://codeforces.com/contest/1278/problem/A 题意: Polycarp has built his own web service. Being ...

随机推荐

  1. JDBC数据库连接(二)

    要想在编程语言中操作数据库,就必须与数据库建立连接. 建立JDBC连接的步骤如下: 导入JDBC包:使用Java语言的import语句在Java代码开头位置导入所需的类. 注册JDBC驱动程序:使JV ...

  2. HDL的三种描述方式

    结构化描述 结构化描述方式是最原始的描述方式,是抽象级别最低的描述方式,但同时也是最接近于实际的硬件结构的描述方式.结构化的描述方式,思路就像在面包板上搭建数字电路一样,唯一的不同点就是我们通过HDL ...

  3. python做中学(七)ord() 函数

    描述 ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII ...

  4. idea配置pyspark

    默认python已经配好,并已经导入idea,只剩下pyspark的安装 1.解压spark-2.1.0-bin-hadoop2.7放入磁盘目录 D:\spark-2.1.0-bin-hadoop2. ...

  5. 常用的app包名和类名

    应用 包名 启动类 QQ com.tencent.mobileqq com.tencent.mobileqq.activity.HomeActivity 微信 com.tencent.mm com.t ...

  6. visdom 简单使用

     官方网址: https://github.com/facebookresearch/visdom 入门教程: http://www.ainoobtech.com/pytorch/pytorch-v ...

  7. Java设计模式:Singleton(单例)模式

    概念定义 Singleton(单例)模式是指在程序运行期间, 某些类只实例化一次,创建一个全局唯一对象.因此,单例类只能有一个实例,且必须自己创建自己的这个唯一实例,并对外提供访问该实例的方式. 单例 ...

  8. 关于excel中的vlookup就是查找当前列对应的下一列的值的使用

    关于excel中的vlookup就是查找当前列对应的下一列的值的使用 vlookup的使用一些说明 vlookup函数一个4个参数解释下 vlookup(查找的值,表格范围,表格范围中第几列的值,0是 ...

  9. 二叉查找树的实现与讲解(C++)

    注:这篇文章源于:https://mp.csdn.net/postedit/99710904, 无需怀疑抄袭,同一个作者,这是我在博客园的账号. 在二叉树中,有两种非常重要的条件,分别是两类数据结构的 ...

  10. python 对Unicode解码

    打印: print('我喜欢你'.encode('unicode_escape')) 得到Unicode编码: b'\\u6211\\u559c\\u6b22\\u4f60 将上面的编码赋值给str后 ...