AtCoder Regular Contest 065
Score : 300 300 300 points
倒着来就行了,正着来会产生歧义匹配, d r e a m e r , d r e a m dreamer,dream dreamer,dream产生歧义,倒着来的话是确定的。
代码
Score : 400 400 400 points
用两个并查集合并起来两个图,让后开一个 m a p map map,让 m p [ p 1 [ i ] , p 2 [ i ] ] + + mp[{p1[i],p2[i]}]++ mp[p1[i],p2[i]]++,最后输出即可。
代码
Score : 900 900 900 points 切比雪夫距离 + 二分
题意:
给你 n n n个点对,问从 a a a出发,每次走 a a a到 b b b的曼哈顿距离,问能走到多少个点对。
1 ≤ n ≤ 1 e 5 1\le n\le 1e5 1≤n≤1e5
思路:
首先将曼哈顿距离转换成切比雪夫距离,距离变成 m a x ( a b s ( x a − x b ) , a b s ( y a − y b ) ) max(abs(x_a-x_b),abs(y_a-y_b)) max(abs(xa−xb),abs(ya−yb)),显然可以排序乱搞。
将 x , y x,y x,y分两次考虑,这里只考虑 x x x,设 a − d a-d a−d的曼哈顿距离是 d d d。
将 x x x从小到大排序,让后离散化一下,将每个点 y y y坐标插到对应的 x x x的位置,之后遍历 x x x,找 x − d x-d x−d的位置,这个时候已经保证了距离为 d d d了,那么我们只需要满足 a b s ( y − y k ) < = d abs(y-y_k)<=d abs(y−yk)<=d即可,可以在 x x x这个位置存的 y y y内二分找到位置算贡献。
但是这样直接写遍历所有位置去重显然是会超时的,考虑优化一下。
有两种,思路是一样的,讲一下简单的。
我们还是找到位置,但是不是在 x − d x-d x−d的这个位置找 y y y,而是我们将 ( x , y ) (x,y) (x,y)存到一个 p a i r pair pair里面,让后二分 ( x − d , y − d ) , ( x − d , y + d ) (x-d,y-d),(x-d,y+d) (x−d,y−d),(x−d,y+d)的位置,由于角上的位置会重复,我们算 y y y的时候去掉即可。假设二分的位置是 ( l , r ) (l,r) (l,r),那么我们给 ( l , r ) (l,r) (l,r)打一个懒标记,代表将 ( l , r ) (l,r) (l,r)内的点合并起来,合并是为了方便最后求答案,答案一定是与 a a a连通的。
这样就可以了,注意细节即可。
代码1
代码2
Score : 900 900 900 points d p dp dp
题意:
给你一个串 s s s,依次进行 m m m次操作,每次可以将 [ l i , r i ] [l_i,r_i] [li,ri]区间内的 s s s随意排序,问最终能生成多少不同的 01 01 01序列,保证询问的 l l l升序。
1 ≤ n ≤ 3000 , 1 ≤ m ≤ 3000 1\le n\le 3000,1\le m\le 3000 1≤n≤3000,1≤m≤3000
这是一个又难又简单的 d p dp dp,考虑到 l l l升序,我们设 d p [ i ] [ j ] dp[i][j] dp[i][j]表示到了第 i i i个,前 i i i个有 j j j个 1 1 1,转移很简单,就是 d p [ i ] [ j ] + = d p [ i − 1 ] [ j ] , d p [ i ] [ j ] + = d p [ i − 1 ] [ j − 1 ] dp[i][j]+=dp[i-1][j],dp[i][j]+=dp[i-1][j-1] dp[i][j]+=dp[i−1][j],dp[i][j]+=dp[i−1][j−1],主要的问题是 j j j的范围。
先考虑这个范围是否能构成,就是先看成 01 01 01可以随意分配,我们先求一下每个位置被覆盖的区间最远能到哪里,设为 m a x r [ i ] maxr[i] maxr[i],那么 [ 1 , m a x r [ i ] ] [1,maxr[i]] [1,maxr[i]]区间内的 01 01 01假设都可以分配给前 i i i个,这样能算出来前 i i i个 1 1 1的个数的上限和下限,让后直接转移即可。
虽然某个状态可能是不存在的,但是不影响答案。
代码