「备战PKUWC2018」The 2017 ACM-ICPC Asia Shenyang Regional Contest 「HDU6217-6229」
2018-01-18 21:01
706 查看
感觉这场比赛质量不是很高,不是打表找规律就是毒瘤坑点,还有高精度(为什么不能交 Python),(还是我比较弱,做不了后面的神题)
比赛结果:
N,M≤2×105 。
题解:
毒瘤数据结构题。对于这张网格图建一棵线段树。每个线段树对应原图的一个矩形(特别的,若 l=r ,则对应两个上下格子所连的一条竖边)。每个 l<r 的线段树节点维护连接左右儿子的横向边。
每个节点维护该区间左上,左下,右上,右下四个角向中间的横向边最长长度,最左边和最右边的纵向边是哪一条,是否在一个环上,与这个区间的答案。
合并时考虑横跨两个区间的横向边是否讲左右区间连成环,与把几条割边加入环,以此更新答案。
实现细节很多,代码量毒瘤,pushup函数共 58 行(我大括号不换行)。
My Code:
N≤1000 。
题解:我不会计算几何(要不然就不会做那个毒瘤数据结构了)。坑。
题解:看题目名先想到 Heron 公式:
S=p(p−a)(p−b)(p−c)−−−−−−−−−−−−−−−−−√=a+b+c2⋅b+c−a2⋅a+c−b2⋅a+b−c2−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−√=3t⋅t⋅(t+2)⋅(t−2)16−−−−−−−−−−−−−−−−−√=143t2⋅(t2−4)−−−−−−−−−−−√=143t4−12t2−−−−−−−−√
即 3t4−12t2 是 4 的倍数的平方。
然后后面的不会证了。。于是打表
t1=4,t2=14,t3=52,t4=194,t5=724,…
找到规律:
tn=4tn−1−tn−2
可以用数学归纳法证明(然而还是不能推出来)
需要高精(不能交 Python)
Hash_Table‘s Code:
N≤150000 。
题解:显然本题没有什么直观的做法。但是考虑一下 (i2+1)modn ,从每个点出发,重复几次走到的不重复的点数量级会下降很快。大约 105 级别的序列 3∼5 次就会下降到几百以内。所以考虑暴力BFS,能够通过此题。
My Code:
题解:有坑。他们的和可能等于 264 ,此时
My Code:
题解:贪心。只有第一只兔子和最后一只兔子可能浪费掉一部分空位,贪心选择最小的放弃,然后填满所有空位即可。
My Code:
题解:把边放到儿子节点上。一个节点对应的边在最后的集合里,当且仅当该点为根的子树有所有 k 种颜色,其他的点也有所有 k 种颜色。答案就是 ∑ni=1[min(size[i],n−size[i])≥k] 。
My Code:
保证能到达右下部分。
N≤10000。
题解:
分析样例后发现一个结论:每个格子有一个大小为 (相邻的非障碍格子数 +1) 的权值。障碍格子的权值为 0 。答案就是右下部分格子权值占所有格子权值的比例。
因为走 ∞ 步,只有长者能够验证结论对不对。
My Code:
比赛结果:
A - BBP Formula
坑。B - Bridge
题意:有一个 2×N 的网格图,相邻的格子之间连边,显然最开始共有 3×N−2 条边。有 M 次操作,每次操作都是形如 opt x0 y0 x1 y1 的形式,若 opt=1 ,则添加 ( x0, y0)↔( x1, y1) 的边,若 opt=2 ,则删除 ( x0, y0)↔( x1, y1) 的边。保证每次操作的边都在最开始的图中存在,即 ( x0, y0) 与 ( x1, y1) 在原图中相邻。(类似 「SHOI2008」堵塞的交通)。你需要在每次操作之后,输出这张图里割边(桥)的条数。N,M≤2×105 。
题解:
毒瘤数据结构题。对于这张网格图建一棵线段树。每个线段树对应原图的一个矩形(特别的,若 l=r ,则对应两个上下格子所连的一条竖边)。每个 l<r 的线段树节点维护连接左右儿子的横向边。
每个节点维护该区间左上,左下,右上,右下四个角向中间的横向边最长长度,最左边和最右边的纵向边是哪一条,是否在一个环上,与这个区间的答案。
合并时考虑横跨两个区间的横向边是否讲左右区间连成环,与把几条割边加入环,以此更新答案。
实现细节很多,代码量毒瘤,pushup函数共 58 行(我大括号不换行)。
My Code:
#include <bits/stdc++.h> #define lc k << 1 #define rc k << 1 | 1 using namespace std; typedef long long ll; int n, m; struct node{ int l, r; int dat[2], dat1[2], dat2[4], dat3[2], dat4; }; struct Seg{ node d[800005]; void pushup(int k){ int l1 = d[lc].r - d[lc].l; int l2 = d[rc].r - d[rc].l; if(d[k].dat[0]){ if(d[lc].dat2[0] == l1) d[k].dat2[0] = d[lc].dat2[0] + 1 + d[rc].dat2[0]; else d[k].dat2[0] = d[lc].dat2[0]; if(d[rc].dat2[1] == l2) d[k].dat2[1] = d[rc].dat2[1] + 1 + d[lc].dat2[1]; else d[k].dat2[1] = d[rc].dat2[1]; }else{ d[k].dat2[0] = d[lc].dat2[0]; d[k].dat2[1] = d[rc].dat2[1]; } if(d[k].dat[1]){ if(d[lc].dat2[2] == l1) d[k].dat2[2] = d[lc].dat2[2] + 1 + d[rc].dat2[2]; else d[k].dat2[2] = d[lc].dat2[2]; if(d[rc].dat2[3] == l2) d[k].dat2[3] = d[rc].dat2[3] + 1 + d[lc].dat2[3]; else d[k].dat2[3] = d[rc].dat2[3]; }else{ d[k].dat2[0] = d[lc].dat2[0]; d[k].dat2[1] = d[rc].dat2[1]; } if(d[lc].dat3[0] == 0) d[k].dat3[0] = d[rc].dat3[0]; else d[k].dat3[0] = d[lc].dat3[0]; if(d[rc].dat3[1] == 0) d[k].dat3[1] = d[lc].dat3[1]; else d[k].dat3[1] = d[rc].dat3[1]; d[k].dat1[0] = d[k].dat1[1] = 0; if(d[k].dat3[0] == 0){ if(d[k].dat[0] == 0 || d[k].dat[1] == 0){ d[k].dat4 = d[lc].dat4 + d[rc].dat4 + 1; }else d[k].dat4 = d[lc].dat4 + d[rc].dat4 + 2; }else{ if(d[k].dat3[0] == d[lc].dat3[0]){ if(d[lc].dat1[0]) d[k].dat1[0] = 1; }else{ if(d[rc].dat1[0]) d[k].dat1[0] = 1; } if(d[k].dat3[1] == d[rc].dat3[1]){ if(d[rc].dat1[1]) d[k].dat1[1] = 1; }else{ if(d[lc].dat1[1]) d[k].dat1[1] = 1; } if(d[k].dat[0] == 0 || d[k].dat[1] == 0){ d[k].dat4 = d[lc].dat4 + d[rc].dat4 + 1; }else if(d[k].dat3[0] != d[lc].dat3[0] || d[k].dat3[1] != d[rc].dat3[1]){ d[k].dat4 = d[lc].dat4 + d[rc].dat4 + 2; }else if(d[lc].r - d[lc].dat2[1] > d[lc].dat3[1] || d[lc].r - d[lc].dat2[3] > d[lc].dat3[1] || d[rc].l + d[rc].dat2[0] < d[rc].dat3[0] || d[rc].dat2[2] + d[rc].l < d[rc].dat3[0] ){ d[k].dat4 = d[lc].dat4 + d[rc].dat4 + 2; }else{ int tmp = d[lc].dat4 + d[rc].dat4 - (d[lc].r - d[lc].dat3[1]) * 2 - (d[rc].dat3[0] - d[rc].l) * 2; if(!d[lc].dat1[1]) tmp--; if(!d[rc].dat1[0]) tmp--; d[k].dat4 = tmp; if(d[lc].dat3[0] == d[lc].dat3[1]) d[k].dat1[0] = 1; if(d[rc].dat3[0] == d[rc].dat3[1]) d[k].dat1[1] = 1; } } //printf("%d %d %d %d %d %d %d %d\n", k, d[k].l, d[k].r, d[k].dat[0], d[k].dat[1], d[k].dat3[0], d[k].dat3[1], d[k].dat4); } void build(int k, int l, int r){ d[k].l = l; d[k].r = r; if(l == r){ d[k].dat[0] = d[k].dat[1] = 0; d[k].dat1[0] = d[k].dat1[1] = 0; d[k].dat2[0] = d[k].dat2[1] = d[k].dat2[2] = d[k].dat2[3] = 0; d[k].dat3[0] = d[k].dat3[1] = l; d[k].dat4 = 1; return; } int mid = (l + r) >> 1; build(lc, l, mid); build(rc, mid + 1, r); d[k].dat[0] = d[k].dat[1] = 1; pushup(k); } void modify1(int k, int pos, int opt){ if(d[k].l == d[k].r){ if(d[k].dat3[0] == 0 && opt == 1){ d[k].dat[0] = d[k].dat[1] = 0; d[k].dat1[0] = d[k].dat1[1] = 0; d[k].dat2[0] = d[k].dat2[1] = d[k].dat2[2] = d[k].dat2[3] = 0; d[k].dat3[0] = d[k].dat3[1] = d[k].l; d[k].dat4 = 1; return; }else if(d[k].dat3[0] != 0 && opt == 2){ d[k].dat[0] = d[k].dat[1] = 0; d[k].dat1[0] = d[k].dat1[1] = 0; d[k].dat2[0] = d[k].dat2[1] = d[k].dat2[2] = d[k].dat2[3] = 0; d[k].dat3[0] = d[k].dat3[1] = 0; d[k].dat4 = 0; return; } } int mid = (d[k].l + d[k].r) >> 1; if(pos <= mid) modify1(lc, pos, opt); if(pos > mid) modify1(rc, pos, opt); pushup(k); } void modify2(int k, int pos, int x, int opt){ if(d[lc].r == pos){ if(d[k].dat[x] == 0 && opt == 1){ d[k].dat[x] = 1; }else if(d[k].dat[x] == 1 && opt == 2){ d[k].dat[x] = 0; } pushup(k); return; } int mid = d[lc].r; if(pos < mid) modify2(lc, pos, x, opt); if(pos > mid) modify2(rc, pos, x, opt); pushup(k); } }Seg; void Solve(){ scanf("%d%d", &n, &m); Seg.build(1, 1, n); //printf("%d\n", Seg.d[1].dat4); for(int i = 1; i <= m; i ++){ int opt, a1, b1, a2, b2; scanf("%d%d%d%d%d", &opt, &a1, &b1, &a2, &b2); if(a1 != a2){ Seg.modify1(1, b1, opt); }else{ if(b1 > b2) swap(b1, b2); Seg.modify2(1, b1, a1, opt); } printf("%d\n", Seg.d[1].dat4); } } int main(){ int T; scanf("%d", &T); for(int I = 1; I <= T; I ++){ Solve(); } return 0; }
C - Empty Convex Polygons
题意:定义 「Ass♂Hole」 「凸洞」(Convex Hole)为一个凸多边形,顶点为给定的点,内部不包含其他给定的点。求出面积最大的「凸洞」。N≤1000 。
题解:我不会计算几何(要不然就不会做那个毒瘤数据结构了)。坑。
D - Defense of the Ancients
坑。E - Five-round Show Hand
坑。F - Heron and His Triangle
题意:定义「Heron 三角形」是一种特殊的三角形,它们的三边长分别是 t−1,t,t+1 (t∈Z)。给定 N 求出 t ≥N 的面积为整数的 t最小的「Heron 三角形」。题解:看题目名先想到 Heron 公式:
S=p(p−a)(p−b)(p−c)−−−−−−−−−−−−−−−−−√=a+b+c2⋅b+c−a2⋅a+c−b2⋅a+b−c2−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−√=3t⋅t⋅(t+2)⋅(t−2)16−−−−−−−−−−−−−−−−−√=143t2⋅(t2−4)−−−−−−−−−−−√=143t4−12t2−−−−−−−−√
即 3t4−12t2 是 4 的倍数的平方。
然后后面的不会证了。。于是打表
t1=4,t2=14,t3=52,t4=194,t5=724,…
找到规律:
tn=4tn−1−tn−2
可以用数学归纳法证明(然而还是不能推出来)
需要高精(不能交 Python)
Hash_Table‘s Code:
#include<bits/stdc++.h> using namespace std; #define debug(x) cout<<#x<<"="<<x<<endl const int maxn = 501; struct Bign { int a[maxn];int len; Bign() { memset(a,0,sizeof a); len=1; } Bign operator = (long long num) { memset(a,0,sizeof a); len=0; while(num) { len++; a[len]=num%10; num/=10; } return *this; } Bign operator + (const long long num) { Bign c; memcpy(c.a,a,sizeof a); c.len=len;c.a[1]+=num; int i=1; while(c.a[i]>=10) { c.a[i+1]+=(c.a[i]/10); c.a[i]%=10; i++; } if(i>c.len) c.len=i; return c; } Bign operator + (const Bign &x) { Bign c; c.len=max(len,x.len); for(int i=1;i<=c.len;i++) { c.a[i]+=a[i]+x.a[i]; c.a[i+1]+=(c.a[i]/10); c.a[i]%=10; } if(c.a[c.len+1]) c.len++; return c; } Bign operator * (const long long num) { Bign c; memcpy(c.a,a,sizeof a); c.len=len; for(int i=1;i<=len;i++) c.a[i]*=num; for(int i=1;i<=len;i++) { c.a[i+1]+=(c.a[i]/10); c.a[i]%=10; } while(c.a[c.len+1]) { c.len++; c.a[c.len+1]+=(c.a[c.len]/10); c.a[c.len]%=10; } return c; } Bign operator * (const Bign &x) { Bign c; c.len=len+x.len; for(int i=1;i<=len;i++) for(int j=1;j<=x.len;j++) c.a[i+j-1]+=a[i]*x.a[j]; for(int i=1;i<c.len;i++) { c.a[i+1]+=(c.a[i]/10); c.a[i]%=10; } while(c.a[c.len]==0&&c.len>1) c.len--; return c; } Bign operator - (const Bign &x) { Bign c; c.len=len; for(int i=1;i<=len;i++) { if(a[i]<x.a[i]) { a[i+1]--; a[i]+=10; } c.a[i]=a[i]-x.a[i]; } while(c.a[c.len]==0&&c.len>1) c.len--; return c; } bool operator < (const Bign &x) const { if(len!=x.len) return len<x.len; for(int i=len;i>=1;i--) if(a[i]!=x.a[i]) return a[i]<x.a[i]; return false; } bool operator == (const Bign &x) const { if(len!=x.len) return false; for(int i=1;i<=len;i++) if(a[i]!=x.a[i]) return false; return true; } bool operator > (const Bign &x) const { return (!(*this<x))&&(!(*this==x)); } bool operator >= (const Bign &x) const { return !(*this<x); } bool operator <= (const Bign &x) const { return !(*this>x); } bool operator != (const Bign &x) const { return !(*this==x); } void read() { char c[maxn]; scanf("%s",c+1); int l=strlen(c+1); for(int i=l;i>=1;i--) a[l-i+1]=c[i]-'0'; len=l; } void print() { for(int i=len;i>=1;i--) printf("%d",a[i]); } void init_max() { for(int i=1;i<=500;i++) a[i]=9; len=10000; } }lim,n,f[maxn]; int T; int main() { lim=1;for(int i=1;i<=31;i++) lim=lim*10; f[0]=2;f[1]=4; for(int i=2;;i++) { f[i]=f[i-1]*4-f[i-2]; if(f[i]>=lim) { break; } } scanf("%d",&T); while(T--) { n.read(); for(int i=1;;i++) if(f[i]>=n) { f[i].print(); puts(""); break; } } return 0; }
G - Infinite Fraction Path
题意:给定一个长为 n 的正整数序列 {Di} (编号 0…n−1)每一位都是[0,9] 之间的整数。第 i 个位置向第 (i2+1)modn 个位置连边。显然从一个位置出发,不断沿着该位置所连出去的边移动,最终会形成无限循环 。现在要从一个点开始走 n 步,每一步把该位置的数字放在一个序列后面。求从哪里开始走形成的序列字典序最大。N≤150000 。
题解:显然本题没有什么直观的做法。但是考虑一下 (i2+1)modn ,从每个点出发,重复几次走到的不重复的点数量级会下降很快。大约 105 级别的序列 3∼5 次就会下降到几百以内。所以考虑暴力BFS,能够通过此题。
My Code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; char ch[150005]; int a[150005]; int n; int ans[150005]; int vis[150005]; int stk[150005], tp; int stk2[150005], tp2; void bfs(){ for(int i = 0; i < n; i ++){ stk[++tp] = i; } for(int I = 1; I <= n; I ++){ int mx = 0; for(int i = 1; i <= tp; i ++){ mx = max(mx, a[stk[i]]); } ans[I] = mx; tp2 = 0; for(int i = 1; i <= tp; i ++){ if(a[stk[i]] == mx){ stk2[++tp2] = stk[i]; } } tp = 0; for(int i = 1; i <= tp2; i ++){ int to = (1ll * stk2[i] * stk2[i] + 1) % n; if(!vis[to]){ vis[to] = 1; stk[++tp] = to; } } for(int i = 1; i <= tp2; i ++){ int to = (1ll * stk2[i] * stk2[i] + 1) % n; vis[to] = 0; } } } int main(){ int T; scanf("%d", &T); for(int I = 1; I <= T; I ++){ scanf("%d", &n); scanf("%s", ch); for(int i = 0; i < n; i ++) a[i] = ch[i] - '0'; bfs(); printf("Case #%d: ", I); for(int i = 1; i <= n; i ++){ printf("%d", ans[i]); } printf("\n"); } return 0; }
H - Legends of the Three Kingdoms
坑。I - Little Boxes
题意:给定四个非负整数 a,b,c,d,每个数小于 262 ,求他们的和。题解:有坑。他们的和可能等于 264 ,此时
unsigned long long存不下,特判一下既可。
My Code:
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ll; ll a, b, c, d; int main(){ int T; scanf("%d", &T); while(T--){ cin >> a >> b >> c >> d; ll sum = a + b + c + d; if(sum == 0 && a != 0){ cout << "18446744073709551616" << endl; }else cout << sum << endl; } return 0; }
J - New Self-describing Sequence
坑。K - Rabbits
题意:有 N(N≥3) 只兔子在数轴上玩♂游♂戏。每次一只兔子跳到两只兔子之间。兔子的坐标只能是整数,且一个点不能有两只或以上兔子。问它们最多能跳几次。题解:贪心。只有第一只兔子和最后一只兔子可能浪费掉一部分空位,贪心选择最小的放弃,然后填满所有空位即可。
My Code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n; int a[100005]; int main(){ int T; scanf("%d", &T); while(T--){ scanf("%d", &n); for(int i = 1; i <= n; i ++) scanf("%d", &a[i]); int sum = 0; for(int i = 1; i < n; i ++) sum = sum + a[i + 1] - a[i] - 1; int t1 = a[2] - a[1] - 1, t2 = a - a[n - 1] - 1; sum = sum - min(t1, t2); printf("%d\n", sum); } return 0; }
L - Tree
题意:一棵树有 N 个节点,要把每个节点染成 K 种颜色之一。定义 Ei 是连接所有第 i 种颜色的点的边集,最大化 ∣∣⋂ni=1Ei∣∣ 。题解:把边放到儿子节点上。一个节点对应的边在最后的集合里,当且仅当该点为根的子树有所有 k 种颜色,其他的点也有所有 k 种颜色。答案就是 ∑ni=1[min(size[i],n−size[i])≥k] 。
My Code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; struct edge{ int to, nxt; }e[100005]; int h[100005], cnt; void addedge(int x, int y){ cnt++; e[cnt].to = y; e[cnt].nxt = h[x]; h[x] = cnt; cnt++; e[cnt].to = x; e[cnt].nxt = h[y]; h[y] = cnt; } int siz[100005]; void dfs(int x, int f){ siz[x] = 1; for(int i = h[x]; i; i = e[i].nxt){ if(e[i].to == f) continue; dfs(e[i].to, x); siz[x] += siz[e[i].to]; } } int n, k; int main(){ int T; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &k); for(int i = 1; i <= n; i ++) h[i] = 0; cnt = 0; for(int i = 1; i < n; i ++){ int x, y; scanf("%d%d", &x, &y); addedge(x, y); } dfs(1, 0); int ans = 0; for(int i = 1; i <= n; i ++){ if(min(siz[i], n - siz[i]) >= k) ans++; } printf("%d\n", ans); } return 0; }
M - Wandering Robots
题意:一个机器人在一个 N×N 的网格里。左上角为 (0,0), 右下角为 (N−1,N−1) 。有一些格子是障碍,不能通过。机器人初始在左上角,每次等概率地向周围格子随机移动。问移动 ∞ 次后停在右下部分 (点的坐标 (x,y) 满足 x+y≥N−1)的概率。保证能到达右下部分。
N≤10000。
题解:
分析样例后发现一个结论:每个格子有一个大小为 (相邻的非障碍格子数 +1) 的权值。障碍格子的权值为 0 。答案就是右下部分格子权值占所有格子权值的比例。
因为走 ∞ 步,只有长者能够验证结论对不对。
My Code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> P; const int dx[] = {1, 0, -1, 0}; const int dy[] = {0, 1, 0, -1}; ll n;int k; map<P, int> mp; ll gcd(ll a, ll b){ return b == 0 ? a : gcd(b, a % b); } ll cal(int x, int y){ ll ret = 5; if(x == 0) ret--; if(x == n - 1) ret--; if(y == 0) ret--; if(y == n - 1) ret--; return ret; } int main(){ int T; scanf("%d", &T); for(int I = 1; I <= T; I ++){ scanf("%lld%d", &n, &k); mp.clear(); ll fm = 5 * n * n - 4 * n; ll fz = 5 * n * (n + 1) / 2 - n - n - 2; for(int i = 1; i <= k; i ++){ int x, y; scanf("%d%d", &x, &y); mp[make_pair(x, y)] += 114514; for(int j = 0; j < 4; j ++){ int xx = x + dx[j], yy = y + dy[j]; if(xx < 0 || xx >= n || yy < 0 || yy >= n) continue; mp[make_pair(xx, yy)] ++; } } for(auto it:mp){ int x = it.first.first, y = it.first.second; ll res = 0; if(it.second > 5) res = cal(x, y); else res = it.second; if(x + y >= n - 1) fz -= res; fm -= res; } ll gc = gcd(fz, fm); fz /= gc; fm /= gc; printf("Case #%d: %lld/%lld\n", I, fz, fm); } return 0; }
相关文章推荐
- 「备战PKUWC2018」2017-2018 ACM-ICPC, Asia Daejeon Regional Contest
- UVALive - 7711 The 2016 ACM-ICPC Asia Jakarta Regional Contest A - Confusing Date Format
- 2017 ACM/ICPC Asia Regional Shenyang Online
- HDU 6203 ping ping ping (LCA + 树状数组, 2017 ACM/ICPC Asia Regional Shenyang Online)
- The 37th ACM/ICPC Asia Regional ChangChun Site Online Contest - K USACO ORZ
- 【树状数组】The 36th ACM/ICPC Asia Regional Beijing Site Online Contest - G Panda
- The 2014 ACM-ICPC Asia Mudanjiang Regional Contest - D
- zoj 3829 Known Notation The 2014 ACM-ICPC Asia Mudanjiang Regional Contest K 贪心
- 回文自动机 + DFS --- The 2014 ACM-ICPC Asia Xi’an Regional Contest Problem G.The Problem to Slow Down You
- zoj 3820 Building Fire Stations The 2014 ACM-ICPC Asia Mudanjiang Regional Contest B题 树的直径
- ZOJ 3545 Rescue the Rabbit(AC自动机+状压DP)(The 2011 ACM-ICPC Asia Dalian Regional Contest)
- The 37th ACM/ICPC Asia Regional Tianjin Site Online Contest - A.B.J
- HDU-2017 ACM/ICPC Asia Regional Qingdao Online-1003-The Dominator of Strings
- The 2013 ACM-ICPC Asia Changsha Regional Contest(2013区域赛练习)
- The 2014 ACM-ICPC Asia Mudanjiang Regional Contest - K
- The 2012 ACM-ICPC Asia Changchun Regional Contest(problem E)
- The 2014 ACM-ICPC Asia Mudanjiang Regional Contest - H
- The 2014 ACM-ICPC Asia Mudanjiang Regional Contest(2014牡丹江区域赛)
- 2014-2015 ACM-ICPC, Asia Xian Regional Contest G The Problem to Slow Down You 回文树
- ZOJ 3819 Average Score The 2014 ACM-ICPC Asia Mudanjiang Regional Contest