CST2018 3-1-1 Sum (15%)

简单的线段树,单点修改,区间求和。

很简单。

CST2018 3-1-2 Max (20%)

高级的线段树。

维护区间最大和,区间和,左边最大和,右边最大和。

单点修改的时候一路吧区间都改了就好了。

求子段最大值也就判断一下左右就好了。

略微复杂。

 #include <cstdio>

 using namespace std;
const int N = 5e5 + ;
const int inf = 1e9;
int n, m;
int a[N]; inline int max(int x, int y) {
return x > y ? x : y;
} struct seg {
seg *ls, *rs;
int sum, mx, mxl, mxr; void* operator new(size_t) {
static seg* c;
c = new seg[];
c -> ls = c -> rs = NULL;
c -> mxl = c -> mxr = c -> mx = c -> sum = ;
return c;
} inline void change_point(int x) { //change the value of a single point
if (x > ) {
sum = mx = mxl = mxr = x;
} else {
sum = x;
mx = mxl = mxr = ;
}
} inline void update() {
if (ls == NULL || rs == NULL) return;
sum = ls -> sum + rs -> sum;
mx = max(max(ls -> mx, rs -> mx), ls -> mxr + rs -> mxl);
mxl = max(ls -> mxl, ls -> sum + rs -> mxl);
mxr = max(rs -> mxr, rs -> sum + ls -> mxr);
} #define mid (l + r >> 1)
void build(int l, int r) {
if (l == r) {
change_point(a[l]);
return;
}
ls = new()seg, ls -> build(l, mid);
rs = new()seg, rs -> build(mid + , r);
update();
} void modify(int l, int r, int pos, int x) {
if (pos < l || r < pos) return;
if (l == r) {
change_point(x);
return;
}
if (pos <= mid) ls -> modify(l, mid, pos, x);
if (mid < pos) rs -> modify(mid + , r, pos, x);
update();
} seg* query(int l, int r, int L, int R) {
seg* ret = new()seg;
if (l == L && R == r) {
*ret = *this;
return ret;
}
if (R <= mid) return ls -> query(l, mid, L, R);
if (L > mid) return rs -> query(mid + , r, L, R); ret -> ls = ls -> query(l, mid, L, mid);
ret -> rs = rs -> query(mid + , r, mid + , R);
ret -> update();
delete ret -> ls;
delete ret -> rs;
return ret;
}
#undef mid
} *segment, *ans; int main() {
int op, x, y;
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i)
scanf("%d", a + i);
segment = new()seg;
segment -> build(, n);
for (int i = ; i <= m; ++i) {
scanf("%d%d%d", &op, &x, &y);
if (op == ) {
segment -> modify(, n, x, y);
} else {
ans = segment -> query(, n, x, y);
printf("%d\n", ans -> mx);
delete ans;
}
}
return ;
}

CST2018 3-2 Not Found (20%)

内存有点小,在考虑按层建立trie树?

不太会。

CST2018 3-3 Hacker (20%)

$18^5$其实并不大,直接预处理hash一下就好了。

冲突的话直接记录输出duplicate。

比较简单。

 #include <cstdio>
#include <cstring>
#include "crc.h" using namespace std;
const char charset[] = "0123456789tsinghua";
const char setlen = ;
const int P2 = ;
const char LEN = ;
int hashTable[P2], flag[P2]; char code[LEN];
char pwd[LEN]; int n;
char salt[LEN];
int saltlen; int test_cnt; inline int encode_char(char ch) {
switch(ch) {
case '' : return ;
case '' : return ;
case '' : return ;
case '' : return ;
case '' : return ;
case '' : return ;
case '' : return ;
case '' : return ;
case '' : return ;
case '' : return ;
case 't' : return ;
case 's' : return ;
case 'i' : return ;
case 'n' : return ;
case 'g' : return ;
case 'h' : return ;
case 'u' : return ;
case 'a' : return ;
}
} inline char decode_char(int x) {
switch(x) {
case : return '';
case : return '';
case : return '';
case : return '';
case : return '';
case : return '';
case : return '';
case : return '';
case : return '';
case : return '';
case : return 't';
case : return 's';
case : return 'i';
case : return 'n';
case : return 'g';
case : return 'h';
case : return 'u';
case : return 'a';
}
} inline int encode(char* str) {
int len = strlen(str);
int encodeNumber = ;
for (int i = ; i < len; ++i)
encodeNumber = * encodeNumber + encode_char(str[i]);
return encodeNumber;
} inline void swap(char &x, char &y) {
char t;
t = x;
x = y;
y = t;
} inline void decode(char* str, int x) {
int t = ;
while (x) {
str[t] = decode_char(x % );
x = x / ;
t += ;
}
for (int i = ; i * < t; ++i) {
swap(str[i], str[t - i - ]);
}
str[t] = ;
} int _union(char *str, unsigned char *input) {
int i = ;
for (; str[i]; ++i) input[i] = str[i];
for (int j = ; salt[j]; ++j) input[i++] = salt[j];
input[i] = ;
return i;
} inline bool check_eq(int x, int y) {
char str[];
decode(str, x);
unsigned char input[];
int i = _union(str, input);
int CRC32Value1 = crc32(input, i);
if (CRC32Value1 == y) return ;
return ;
} void insert_hash(int x, int y) {
int hash = ((x % P2) + P2) % P2;
while (hashTable[hash] != -) {
if (check_eq(hashTable[hash], x)) {
flag[hash] = ;
return;
}
hash += ;
}
hashTable[hash] = y;
} void update_pwd(char x) {
for (int i = ; i <= ; ++i)
pwd[i] = pwd[i + ];
pwd[] = x;
pwd[] = ;
} void get_hash(int x) {
int hash = ((x % P2) + P2) % P2;
while (hashTable[hash] != -) {
if (check_eq(hashTable[hash], x)) {
if (flag[hash] == ) {
puts("duplicate");
return;
}
char ans[];
decode(ans, hashTable[hash]);
printf("%s\n", ans);
update_pwd(ans[]);
return;
}
hash += ;
}
puts("No");
} void make_hash(char* str) {
unsigned char input[];
int i = _union(str, input);
int CRC32Value = crc32(input, i); //calculate CRC32
insert_hash(CRC32Value, encode(str));
} void dfs(int len) {
for (int i = ; i < setlen; ++i) {
code[len] = charset[i];
code[len + ] = ;
make_hash(code);
if (len < ) dfs(len + );
}
} void find_hash() {
int CRC32Value;
scanf("%d", &CRC32Value);
get_hash(CRC32Value);
} int main() {
int len;
int oper;
scanf("%d\n", &n);
scanf("%s\n", salt);
saltlen = strlen(salt);
for (int i = ; i < P2; ++i)
hashTable[i] = -, flag[i] = ; dfs();
while (n--) {
scanf("%d\n", &oper);
if (oper == ) {
find_hash();
}
if (oper == ) {
make_hash(pwd);
}
}
return ;
}

CST2018 3-4 kth (20%)

可以先通过3n次比较进行排序。

一个数组的话直接二分就好了。

要是两个数组可以丢堆里面。

三个不会【摊手

 #include "kth.h"
#include <cstdio> using namespace std;
const int N = 5e5 + ;
const int K = 26e5 + ; int X[N], Y[N], Z[N]; template<class T> inline void swap(T &x, T &y) {
register T tmp;
tmp = x, x = y, y = tmp;
} struct heap {
heap *ls, *rs;
int _X, _Y, _Z;
int dep; void *operator new(size_t, int __X, int __Y, int __Z) {
static heap mempool[K], *c = mempool;
c -> ls = c -> rs = NULL;
c -> dep = ;
c -> _X = __X, c -> _Y = __Y, c -> _Z = __Z;
return c++;
} friend inline bool compare_greater(heap *x, heap *y) {
return compare(X[y -> _X], Y[y -> _Y], Z[y -> _Z], X[x -> _X], Y[x -> _Y], Z[x -> _Z]);
} #define Dep(p) (p ? p -> dep : 0)
friend heap* merge(heap *x, heap *y) {
if (!x) return y;
if (!y) return x;
if (compare_greater(x, y)) swap(x, y);
x -> rs = merge(x -> rs, y);
if (Dep(x -> rs) > Dep(x -> ls)) swap(x -> ls, x -> rs);
x -> dep = Dep(x -> rs) + ;
return x;
}
#undef Dep inline heap* pop() {
return merge(ls, rs);
}
} *root; inline bool check_less(int flag, int x, int y) {
if (flag == ) return compare(x, , , y, , );
if (flag == ) return compare(, x, , , y, );
if (flag == ) return compare(, , x, , , y);
} inline void swap(int *a, int x, int y) {
int t;
t = a[x];
a[x] = a[y];
a[y] = t;
} void sort(int l, int r, int flag, int *A) {
if (l >= r) return;
swap(A[(l + r >> )], A[r]);
int x = A[r], i = l - ;
for (int j = l; j <= r; ++j) {
if (check_less(flag, A[j], x)) {
i++;
swap(A, i, j);
}
}
i += ;
A[r] = A[i];
A[i] = x;
sort(l, i - , flag, A);
sort(i + , r, flag, A);
} void init(int n) {
for (int i = ; i <= n; ++i)
X[i] = Y[i] = Z[i] = i;
sort(, n, , X);
sort(, n, , Y);
sort(, n, , Z);
} inline void insert(int _X, int _Y, int _Z) {
root = merge(root, new(_X, _Y, _Z)heap);
} void get_kth(int n, int k, int *x, int *y, int *z) {
init(n); //sort for x, y and z
root = new(, , )heap;
int _X, _Y, _Z;
while (--k) {
_X = root -> _X, _Y = root -> _Y, _Z = root -> _Z;
if (_Z != n) insert(_X, _Y, _Z + );
if (_Z == ) {
if (_Y == && _X != n) insert(_X + , _Y, _Z);
if (_Y != n) insert(_X, _Y + , _Z);
}
root = root -> pop();
}
*x = X[root -> _X], *y = Y[root -> _Y], *z = Z[root -> _Z];
}

CST2018 3-5 Prefix (20%)

一道简单的KMP,就是考虑每个节点为结尾多出来多少重复的。

比较简单。

 #include <cstdio>
#include <cstring> using namespace std;
typedef long long ll;
const int N = 2e7 + ; int f[N];
int cnt[N];
char str[N];
int len; void KMP(int len) {
int i = , j = -;
f[] = -;
while (i < len) {
if (j == - || str[i] == str[j]) {
i += ;
j += ;
f[i] = j;
}
else j = f[j];
}
f[] = ;
} int main() {
gets(str);
len = strlen(str);
KMP(len);
ll ans = ;
memset(cnt, , sizeof(cnt));
for (int i = ; i <= len; ++i) {
cnt[i] = cnt[f[i]];
cnt[i]++;
ans += cnt[i];
}
printf("%lld\n", ans);
return ;
}

CST2018 3-6 Match (20%)

Treap的应用:

插入:基本操作。

删除:基本操作。

翻转:基本操作。

比较大小:用hash比较。

所以要记录两个值:以某个节点为根的顺序的hash和逆序的hash。

写起来比较麻烦。

 #include <cstdio>

 using namespace std;
const int N = 4e5 + ;
const int LEN = 10e5 + ;
const int P1 = ;
const int P2 = 1e9 + ; int n, m; template<class T> inline void swap(T &x, T &y) {
register T tmp;
tmp = x, x = y, y = tmp;
} namespace treap {
struct node;
node *root, *null;
int base[LEN]; inline int cal_hash(int hash1, int sz1, int ch, int hash2, int sz2) {
int ret = (hash2 + 1ll * ch * base[sz2] % P2) % P2;
ret = (ret + 1ll * hash1 * base[sz2 + ] % P2) % P2;
return ret;
} struct node {
node *ls, *rs;
int sz, rev, hashl, hashr;
int ch; #define Len (1 << 16)
inline void* operator new(size_t, int _v = ) {
static node *mempool, *c;
if (mempool == c)
mempool = (c = new node[Len]) + Len;
c -> ls = c -> rs = null;
c -> sz = ;
c -> rev = ;
c -> hashl = c -> hashr = c -> ch = _v;
return c++;
}
#undef Len inline void reverse() {
rev ^= ;
swap(ls, rs);
swap(hashl, hashr);
} inline node* push() {
if (rev) {
ls -> reverse(), rs -> reverse();
rev = ;
}
return this;
} inline node* update() {
sz = ls -> sz + rs -> sz + ;
ls -> push(), rs -> push();
hashl = cal_hash(ls -> hashl, ls -> sz, ch, rs -> hashl, rs -> sz);
hashr = cal_hash(rs -> hashr, rs -> sz, ch, ls -> hashr, ls -> sz);
return this;
}
}; inline void init() {
null = new()node;
null -> ls = null -> rs = null;
null -> sz = null -> hashl = null -> hashr = ; base[] = ;
for (int i = ; i < LEN; ++i)
base[i] = 1ll * base[i - ] * P1 % P2;
} inline unsigned int Rand() {
static unsigned int res = ;
return res += res << | ;
}
inline int random(int x, int y) {
return Rand() % (x + y) < x;
} void build(node *&p, int l, int r, int *a) {
if (l > r) {
p = null;
return;
}
p = new(a[l + r >> ])node;
if (l == r) {
p -> update();
return;
}
build(p -> ls, l, (l + r >> ) - , a);
build(p -> rs, (l + r >> ) + , r, a);
p -> update();
} void merge(node *&p, node *x, node *y) {
if (x == null || y == null)
p = x == null ? y -> push() : x -> push();
else if (random(x -> sz, y -> sz)) {
p = x -> push();
merge(p -> rs, x -> rs, y);
} else {
p = y -> push();
merge(p -> ls, x, y -> ls);
}
p -> update();
} void split(node *p, node *&x, node *&y, int k) {
if (!k) {
x = null, y = p -> push();
return;
}
if (k == p -> sz) {
x = p -> push(), y = null;
return;
}
if (p -> ls -> sz >= k) {
y = p -> push();
split(p -> ls, x, y -> ls, k);
y -> update();
} else {
x = p -> push();
split(p -> rs, x -> rs, y, k - p -> ls -> sz - );
x -> update();
}
}
}
using namespace treap; int a[N]; int main() {
char ch;
int op;
int pos, tmp;
int pos1, pos2, len;
node *x, *y, *z;
int hash1, hash2, ans = ;
scanf("%d %d\n", &n, &m);
for (int i = ; i <= n; ++i) {
ch = getchar();
while (!('a' <= ch && ch <= 'z')) ch = getchar();
a[i] = ch - 'a' + ;
} init();
build(root, , n, a);
while (m--) {
scanf("%d", &op);
if (op == ) {
scanf("%d", &pos);
ch = getchar();
while (!('a' <= ch && ch <= 'z')) ch = getchar();
tmp = ch - 'a' + ;
split(root, x, y, pos);
z = new(tmp)node;
merge(root, x, z); merge(root, root, y);
//root = x + y, new_root = x + z + y
}
if (op == ) {
scanf("%d", &pos);
split(root, x, y, pos - ); split(y, y, z, );
merge(root, x, z);
//root = x + y + z, new_root = x + z
}
if (op == ) {
scanf("%d %d", &pos1, &pos2);
split(root, x, y, pos1 - ), split(y, y, z, pos2 - pos1 + );
y -> reverse();
merge(root, x, y -> push()), merge(root, root, z);
//root = x + y + z, y -> rev
}
if (op == ) {
scanf("%d %d %d", &pos1, &pos2, &len);
split(root, x, y, pos1 - ), split(y, y, z, len);
hash1 = y -> hashl;
merge(root, x, y), merge(root, root, z); split(root, x, y, pos2 - ), split(y, y, z, len);
hash2 = y -> hashl;
merge(root, x, y), merge(root, root, z);
ans += (hash1 == hash2);
}
}
printf("%d\n", ans);
return ;
}

CST2018 3-7 History (15%)

强制在线。

简单hash。

CST2018 3-8 Shortest (15%)

堆优化Dijkstra。

其实我觉得spfa加SLF还是能过。。。

Tsinghua 2018 DSA PA3简要题解的更多相关文章

  1. Tsinghua 2018 DSA PA2简要题解

    反正没时间写,先把简要题解(嘴巴A题)都给他写了记录一下. upd:任务倒是完成了,我也自闭了. CST2018 2-1 Meteorites: 乘法版的石子合并,堆 + 高精度. 写起来有点烦貌似. ...

  2. A · F · O —— JLOI2018翻车记(附Day1简要题解)

    JLOI2018翻车记 并不知道该怎么写... 算了还是按照标准剧情来吧 这应该是一篇写得非常差的流水账... 2018.04.04 Day -1 省选前在机房的最后一天. 压力并不是很大,毕竟联赛 ...

  3. Noip 2014酱油记+简要题解

    好吧,day2T1把d默认为1也是醉了,现在只能期待数据弱然后怒卡一等线吧QAQ Day0 第一次下午出发啊真是不错,才2小时左右就到了233,在车上把sao和fate补掉就到了= = 然后到宾馆之后 ...

  4. Codeforces 863 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...

  5. HNOI2018简要题解

    HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...

  6. JXOI2018简要题解

    JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法 ...

  7. BJOI2018简要题解

    BJOI2018简要题解 D1T1 二进制 题意 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是 \(3\) 的倍数.他想研究对于二进制,是否也有类似的性质. 于是他生 ...

  8. CQOI2018简要题解

    CQOI2018简要题解 D1T1 破解 D-H 协议 题意 Diffie-Hellman 密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码)的情况下,通过不安全的信 ...

  9. AtCoder ExaWizards 2019 简要题解

    AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...

随机推荐

  1. Django数据查询方法总结

      __exact 精确等于 like ‘aaa’__iexact 精确等于 忽略大小写 ilike ‘aaa’__contains 包含 like ‘%aaa%’__icontains 包含 忽略大 ...

  2. js中的数组方法

    数组的方法有数组原型方法,也有从object对象继承来的方法,这里我们只介绍数组的原型方法,数组原型方法主要有以下这些: join()push()和pop()shift() 和 unshift()so ...

  3. LeetCode 链表(旋转链表61)

    /* * 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. * 构造一个环,对链表进行处理. * *实现原理:先遍历一遍,得出链表长度,注意K可能大于len,之后令k% ...

  4. MTK-TP(触屏)解读一

    MTK中的TP代码结构并不复杂,相比于其他的系统更为的简单些.它使用的是input子系统,通过该系统来上报触摸按键. 首先我们来看看TP的文件夹下的各代码文件的功能. 文件名 具体功能 关系文件 tp ...

  5. Josephina and RPG HDU - 4800

    A role-playing game (RPG and sometimes roleplaying game) is a game in which players assume the roles ...

  6. IIS的地址指向

    地址指向 1)AuthwebAPI  修改web.xml文件 <connectionStrings> data source 改成当前虚拟环境的IP指向 </connectionSt ...

  7. PL/SQL变量和类型

    变量 在定义变量时一定要为其指定一个类型,类型可以是PL/SQL类型或SQL语言的类型,一旦变量的类型确定,那么变量中所能存储的值也就确定了,因此尽管变量的值会经常改变,但是值的类型是不可以变化的. ...

  8. 【Alpha】Scrum Meeting 11

    目录 前言 任务分配 燃尽图 会议照片 签入记录 前言 第11次会议于4月16日18:15在一公寓三楼召开. 交流确认了任务进度,讨论项目发布事宜,分配下一阶段任务.时长45min. 任务分配 姓名 ...

  9. Mysql与Postgresql

    在经过一段时间的数据库学习之后,我接触到了Mysql与Postgresql两种数据库管理系统,由于我对这两者的理解都停留在很浅的层面,就不在此比较两者的好坏,主要在这里比较一下两者的入门指令(当然两者 ...

  10. springBoot整合jpa

    https://blog.csdn.net/qq_35180973/article/details/82316438 总体来讲只是在service调用dao的时候用接口代替dao继承CrudRepos ...