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. AcWing 166. 数独

    题目地址 https://www.acwing.com/problem/content/description/168/ 题目描述 数独是一种传统益智游戏,你需要把一个9 × 9的数独补充完整,使得图 ...

  2. 题解:swj社会摇成佛第六课

    题目链接 solution: dp f[i]表示lhy小伙身长为i,能砍得的最优解 f[i]=f[j]*f[i-j]; public class CuttingRope01 { public stat ...

  3. autocad2014一直显示正在检查许可

    64位CAD2014安装成功后启动时在检查许可卡住的解决方法,以下方法经本人测试,真实可行.1.下载CCcleaner.2.将CCcleaner设置成中文版,英文好的继续第三步.(设置方法:选项opt ...

  4. Least Common Multiple (HDU - 1019) 【简单数论】【LCM】【欧几里得辗转相除法】

    Least Common Multiple (HDU - 1019) [简单数论][LCM][欧几里得辗转相除法] 标签: 入门讲座题解 数论 题目描述 The least common multip ...

  5. 4. 语义"陷阱"

    1. 假定对于下标越界的数组元素取其地址也是非法的,那么对于本书3.6(该标题下为4.6)节中的bufwrite程序应该如何书写? void bufwrite(char *p, int n){ whi ...

  6. source vimrc的时候报错:.vimrc:1: command not found: syntax

    vim的配置如下: 1 syntax enable //语法高亮 2 set number //显示行号 3 set cursorline //突出显示当前行 4 set ruler //打开状态栏标 ...

  7. IT兄弟连 Java语法教程 流程控制语句 分支结构语句5

    5  switch-case条件语句 Java中的第二种分支控制语句时switch语句,switch语句提供了多路支持,因此可以使程序在多个选项中进行选择.尽管一系列嵌套if语句可以执行多路测试,然而 ...

  8. WildFly16.0配置数据源并测试

    目前网络上罕有近期版本的配置,本人经多次尝试网络中不同方式配置,在Testing Connection一步中尽皆失败后,查询官方文档未果,摸索出一条可行之路,在此分享于诸位朋友. [../wildfl ...

  9. idea的service注入mapper报错

    一.问题 idea的java项目中,service类中注入mapper报错 二.解决 方法1 在mapper类上加上  @Repository 注解即可,当然不加也行,程序也不回报错,是idea的误报 ...

  10. PDF怎么转换为CAD文件?这两种方法你的会

    在日常的办公中,我们最常见的文件格式就是PDF格式的,因为PDF文件的安全性是比较高的,可以防止不小心触碰到键盘修改文件内容,而且PDF文件便于进行文件的传输.但是有时候也需要将PDF转换成CAD,那 ...