2019牛客暑期多校训练营(第三场) J LRU management 模拟链表操作
输入n, m,n表示n种操作,m表示最多可以容纳m个串。
第一种操作:先在容器里找是否存在这个串,如果不存在,则添加在末尾,这个串携带了一个值v。
如果存在,则先把之前存在的那个拿出来,然后在后面添加这个串,注意此时输入的这个v值不管用!!!!,v还是以前的那个v.
第二种操作:先在这个容器内是否存在这个串,如果存在则看v值,v值为-1, 0, 1,分别表示左边那个,自己,右边那个,如果存在则输出那个串携带的v值,不存在则输出invalid.
#include<bits/stdc++.h> using namespace std;
const int M = 5e5 + ;
typedef pair<int, int> pii;
//flag表示v值,ind表示是第几个串,如果先出去了再进来算另外一个
int flag[M * ], ind[M * ];
int t, n, m, tot;
char s[];
int tree[M * ][];
//判断这个串是否出现过与是否已经出去了。下标对应cnt
int vis[M];
//左边,右边。
int le[M], re[M];
//保存v值。下标对应cnt
int ans[M];
容器头元素,尾元素。
int mi, ma; void add(char ch[], int in, int val) {
int root = , len = strlen(ch);
for(int i = ; i < len; i++) {
int id = ch[i] - '';
if(!tree[root][id]) {
memset(tree[tot], , sizeof(tree[tot]));
ind[tot] = -;
flag[tot] = -;
tree[root][id] = tot++;
}
root = tree[root][id];
}
ind[root] = in;
flag[root] = val;
} pii findx(char ch[]) {
int root = , len = strlen(ch);
for(int i = ; i < len; i++) {
int id = ch[i] - '';
root = tree[root][id];
if(!root) return pii(-, -);
}
return pii(ind[root], flag[root]);
} int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
tot = ;
memset(tree[], , sizeof(tree[]));
int opt, v;
//给串标号,如果出去了再进来也要++.
int cnt = ;
//表示容器里有几个元素。
int num = ;
mi = , ma = -;
for(int i = ; i <= n; i++) {
scanf("%d%s%d", &opt, s, &v);
int tmp = ma;
if(opt == ) {
pii p = findx(s);
if(p.first == - || vis[p.first] == ) {
cnt++;
vis[cnt] = ;
le[cnt] = re[cnt] = -;
ans[cnt] = v;
add(s, cnt, v);
if(tmp != -) re[tmp] = cnt;
le[cnt] = tmp;
ma = cnt;
num++;
printf("%d\n", v);
}
else {
//更改的是第一个
if(p.first == mi) mi = re[mi];
if(num == ) mi = p.first;
printf("%d\n", p.second);
//注意这个!!!!更之前tmp有关,可能更改的是最后一个
if(p.first == ma) continue;
//链表操作。
if(le[p.first] != -) re[le[p.first] ] = re[p.first];
if(re[p.first] != -) le[re[p.first] ] = le[p.first];
//!!!!因为ma可能更改了,所以之前要特判一下p.first == ma.
if(tmp != -) re[tmp] = p.first;
le[p.first] = tmp;
re[p.first] = -;
ma = p.first;
}
}
else {
pii p = findx(s);
if(p.first != - && vis[p.first] == ) {
if(v == ) printf("%d\n", p.second);
else if(v == -) {
if(le[p.first] != - && vis[p.first ] == ) printf("%d\n", ans[le[p.first] ]);
else printf("Invalid\n");
}
else {
if(re[p.first] != - && vis[p.first ] == ) printf("%d\n", ans[re[p.first] ]);
else printf("Invalid\n");
}
}
else printf("Invalid\n");
}
if(num > m) {
num--;
//表示出容器。
vis[mi] = ;
int tm = re[mi];
if(tm != -) le[tm] = -;
re[mi] = -;
mi = tm;
}
}
}
return ;
}
/*
1
8 3
0 0101010 1
0 0101011 2
1 0101010 1
0 1100000 3
0 0101011 -1
0 1111111 4
1 0101011 -1
1 0101010 0
*/
并查集加速链表操作
#include <bits/stdc++.h> using namespace std;
const int maxn = 1e5 + ;
unordered_map<int, int> fa; int findfa(int x) {
if (!fa.count(x)) return x;
return fa[x] = findfa(fa[x]);
} int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int n, q;
scanf("%d %d", &n, &q);
int op, x;
while (q--) {
scanf("%d %d", &op, &x);
if (op == ) {
fa[x] = findfa(x + );
} else {
int ans = findfa(x);
if (ans > n) ans = -;
printf("%d\n", ans);
}
}
return ;
}
2019牛客暑期多校训练营(第三场) J LRU management 模拟链表操作的更多相关文章
- 2019牛客暑期多校训练营(第三场)H题目
题意:给你一个N×N的矩阵,求最大的子矩阵 满足子矩阵中最大值和最小值之差小于等于m. 思路:这题是求满足条件的最大子矩阵,毫无疑问要遍历所有矩阵,并判断矩阵是某满足这个条件,那么我们大致只要解决两个 ...
- 2019牛客暑期多校训练营(第三场)- F Planting Trees
题目链接:https://ac.nowcoder.com/acm/contest/883/F 题意:给定n×n的矩阵,求最大子矩阵使得子矩阵中最大值和最小值的差值<=M. 思路:先看数据大小,注 ...
- 2019牛客暑期多校训练营(第三场) F.Planting Trees(单调队列)
题意:给你一个n*n的高度矩阵 要你找到里面最大的矩阵且最大的高度差不能超过m 思路:我们首先枚举上下右边界,然后我们可以用单调队列维护一个最左的边界 然后计算最大值 时间复杂度为O(n*n*n) # ...
- 2019牛客暑期多校训练营(第六场)J Upgrading Technology
传送门 题意: 就是给你n个技能,每个技能最高升到m级,每升一级就是耗费Cij钱,这个Cij可能是负的,如果所有技能都升到或者说超过j等级,就会获得Dj钱,这个Dj也有可能是负值,让你求你最多得到多少 ...
- 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)
题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9: 对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可. 后者mod=1e9,5才 ...
- 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...
- 2019牛客暑期多校训练营(第一场) B Integration (数学)
链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...
- 2019牛客暑期多校训练营(第二场)F.Partition problem
链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...
- 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...
随机推荐
- linux--权限管理和用户管理
权限 查看详细信息 ls -l - rw- r-- r-- 1 tom root 0 Jun 20 00:02 apple.txt 1 2 3 4 5 6 7 8 9 10 #1 文件的类型 #[-: ...
- ansible安装-本机测试
环境:centos7 yum源:网络yum源 安装: 默认yum安装,也可以自己编译安装 yum -y install ansible 本机测试: [root@localhost ~]# ansibl ...
- html中引入调用另一个html文件
第一种: <body> <div id="page1"></div> <div id="page2"></ ...
- 3ds Max File Format (Part 6: We get signal)
Let's see what we can do now. INode *node = scene.container()->scene()->rootNode()->find(uc ...
- Java修饰符类型
转自原文:http://www.yiibai.com/java/java_modifier_types.html 修饰符是添加到这些定义来改变它们的含义的关键词. Java语言有各种各样修饰词,其中包 ...
- 题解【洛谷P3478】[POI2008]STA-Station
题面 设\(dp_i\)表示以\(i\)为根节点时所有节点的深度之和. 首先以 \(1\) 为根求出所有点深度之和\(dp_1\),并预处理每个点的子树大小. 设 \(v\) 是 \(u\) 的孩子, ...
- 题解【洛谷P1618】 三连击(升级版)
设三个数分别为n1.n2.n3,因为三个数的比为A:B:C,取一份量i,使得A·i=x,B·i=y,C·i=z(·是*的意思). 所以我们的代码只需要枚举i,并以此判断n1.n2.n3是否为三位数且包 ...
- cat 显示文本、less 分屏显示文本、more 分页显示文件、head 显示文件的前面的内容、cut 切割、paste合并、wc用来对文本进行统计、sort排序、权限、关闭文件、vim的使用
cat 显示文本 -E 显示结尾的$符 -n 对显示的每一行进行编号 -b 对非空行进行编号 -s 对连续的空行进行压缩 tac 倒序显示 less 分屏显示文本 向下翻一屏 空格 向下翻一行 回车 ...
- [CCPC2019秦皇岛] E. Escape
[CCPC2019秦皇岛E] Escape Link https://codeforces.com/gym/102361/problem/E Solution 观察到性质若干然后建图跑最大流即可. 我 ...
- Python + Selenium +Chrome 批量下载网页代码修改【新手必学】
Python + Selenium +Chrome 批量下载网页代码修改主要修改以下代码可以调用 本地的 user-agent.txt 和 cookie.txt来达到在登陆状态下 批量打开并下载网页, ...