[2019CSP-S Day1]提高组Day1题解(格雷码[模拟(k转二进制取反的做法带证明)] + 括号树[DP] + 树上的数(暴力+菊花图+单链))

Day1

  • T1:格雷码
    • 题目
    • 题解
    • 代码实现
  • T2:括号树
    • 题目
    • 题解
    • 代码实现
  • T3:树上的数
    • 题目
    • 10pts暴力题解
    • 代码实现
    • 25pts菊花图题解
    • 代码实现
    • 25pts单链题解
    • 代码实现

T1:格雷码

题目

通常,人们习惯将所有 n位二进制串按照字典序排列,例如所有2位二进制串按字典序从小到大排列为: 00, 01, 10, 11。
格雷码(Gray Code)是一种特殊的 n位二进制串排列法,它要求相邻的两个二进制串间恰好有一位不同,特别地,第一个串与最后一个串也算作相邻。
所有 2位二进制串按格雷码排列的一个例子为: 00, 01, 11, 10。
n 位格雷码不止一种,下面给出其中一种格雷码的生成算法:
1位格雷码由两个1 位二进制串组成,顺序为:0, 1。
n+1位格雷码的前2n个二进制串,可以由依此算法生成的 n 位格雷码(总共2n个 n 位二进制串)按顺序排列,再在每个串前加一个前缀 0 构成。
n + 1 位格雷码的后 2n个二进制串,可以由依此算法生成的 n 位格雷码(总共2n个 n 位二进制串)按逆序排列,再在每个串前加一个前缀 1 构成。
综上, n + 1 位格雷码,由 n 位格雷码的 2n个二进制串按顺序排列再加前缀 0,和按逆序排列再加前缀 1 构成,共2{n+1}个二进制串。另外,对于 n 位格雷码中的2n个二进制串,我们按上述算法得到的排列顺序将它们从0 ∼ 2n-1编号。
按该算法, 2 位格雷码可以这样推出:
已知 1 位格雷码为 0, 1。
前两个格雷码为 0 1, 0 1。后两个格雷码为 1 1, 1 0。合并得到 00, 01, 11, 10,编号依次为 0 ∼ 3。
同理, 3 位格雷码可以这样推出:
已知 2 位格雷码为: 00, 01, 11, 10。
前四个格雷码为:0 00, 0 01, 0 11, 0 10。后四个格雷码为:1 10, 1 11, 1 01,1 00。合并得到: 000, 001, 011, 010, 110, 111, 101, 100,编号依次为 0 ∼ 7。
现在给出 n, k,请你求出按上述算法生成的 n 位格雷码中的 k 号二进制串。
输入描述:
仅一行两个整数 n,k,意义见题目描述。
输出描述:
仅一行一个 n 位二进制串表示答案。
示例1
输入
2 3
输出
10
说明
2 位格雷码为:00,01,11,10,编号从 0∼3,因此 3 号串是 10
示例2
输入
3 5
输出
111
说明
3 位格雷码为:000,001,011,010,110,111,101,100,编号从 0∼7,因此 5 号串是 111。
备注:
对于 50% 的数据:n≤10
对于 80% 的数据:k≤5×106
对于 95% 的数据:k≤263−1
对于 100% 的数据:1≤n≤64 ,0≤k<2n

题解

额额额这道题就是一道模拟题,并不打算展开讲,这里的代码实现完全只是保存个代码罢了。这道题有很多方法实现,很多人的方法由于涉及到二的n次方带左移又没有开ULL会爆掉更多的分,这告诉我们在考场上要评估自己代码的危险性!!


看到格雷码的生成规律发现了,如果属于下半部分,它后面是与上半部分成镜面对称的,意思就是属于上半部分的从上往下第x个对应着下半部分的从下往上第x个,就当前那一位而言。。

所以我们可以把k转换成二进制,然后开始扫,遇到第一个1就输出1然后把k的当前位及其以后取个反,继续往右操作

代码实现

#include <cstdio>
#include <iostream>
using namespace std;
int n;
unsigned long long k;
int main() {scanf ( "%d", &n );cin >> k;for ( int i = n - 1;i >= 0;i -- ) {int flag = ( k >> i ) & 1;if ( flag ) printf ( "1" );else printf ( "0" );if ( flag ) k = ~k;}return 0;
}

可能会一脸蒙蔽为什么这么简单就可以,或者为什么是取反呢??接下来为大家带来比较简略的证明
在这里插入图片描述
假设n=3时,所有的情况从零开始编号依次如图所示,我们开始找规律,如果k的二进制前x个都是零,那么它就一直属于上半部分,我们观察得到,上半部分的规律就是对于y号位而言,把y-1号位的属于y号位的2(y-1)个数分成上下两半,都是上半部分是零,下半部分是1


如果出现了一个1,下半部分的规律就是对于y号位而言,把y-1号位的属于y号位的2(y-1)个数分成上下两半,上面都是1,下面都是0,直到出现了第二个1,才改变了它的规律变成上半部分是0,下半部分是1


所以能明白为什么要这么写了吗??其实跟我在考场上找到的规律是一样的,但是码力差距,就打出了天壤之别,接下来的就是我在考场时自己写的比较复杂的代码,可以跳过

#include <cstdio>
#include <iostream>
using namespace std;
#define LL unsigned long long
int n;
LL k;
LL pre[70];
void dfs1 ( int x, LL y );
void dfs2 ( int x, LL y );void dfs1 ( int x, LL y ) {if ( x == 0 )return;if ( y >= pre[x - 1] ) {printf ( "0" );dfs1 ( x - 1, y - pre[x - 1] );}else {printf ( "1" );dfs2 ( x - 1, y );}
}void dfs2 ( int x, LL y ) {if ( x == 0 )return;if ( y >= pre[x - 1] ) {printf ( "1" );dfs1 ( x - 1, y - pre[x - 1] );}else {printf ( "0" );dfs2 ( x - 1, y );}
}int main() {scanf ( "%d", &n );cin >> k;pre[0] = 1;for ( int i = 1;i <= 64;i ++ )pre[i] = pre[i - 1] * 2;if ( k >= pre[n - 1] ) {printf ( "1" );dfs1 ( n - 1, k - pre[n - 1] );}else {printf ( "0" );dfs2 ( n - 1, k );}return 0;
}

T2:括号树

题目

本题中合法括号串的定义如下:
()是合法括号串。
如果 A 是合法括号串,则 (A) 是合法括号串。
如果 A, B是合法括号串,则 AB 是合法括号串。
本题中子串与不同的子串的定义如下:
字符串 S 的子串是 S 中连续的任意个字符组成的字符串。 S 的子串可用起始位置 l 与终止位置 r 来表示,记为 (1≤l≤r≤∣S∣(1 \leq l \leq r \leq|S|1lrS,∣S∣表示S的长度)。
S的两个子串视作不同当且仅当它们在S中的位置不同,即l不同或r不同。
【题目描述】
一个大小为 n 的树包含n个结点和n − 1 条边,每条边连接两个结点,且任意两个结点间有且仅有一条简单路径互相可达。
小 Q 是一个充满好奇心的小朋友,有一天他在上学的路上碰见了一个大小为 n 的树,树上结点从 1 ∼ n 编号, 1 号结点为树的根。除 1 号结点外,每个结点有一个父亲结点, u(2≤u≤n)u \ (2 \leq u \leq n)u (2un)号结点的父亲为fu(1≤fu<u)f_{u} \ \left(1 \leq f_{u}<u\right)fu (1fu<u)号结点。
小 Q 发现这个树的每个结点上恰有一个括号,可能是’(‘或’)’。小Q定义sis_isi为:将根结点到 i 号结点的简单路径上的括号,按结点经过顺序依次排列组成的字符串。
显然sis_isi是个括号串,但不一定是合法括号串,因此现在小 Q 想对所有的i(1≤i≤n)i\ (1 \leq i \leq n)i (1in)求出,sis_isi中有多少个互不相同的子串是合法括号串。
这个问题难倒了小 Q,他只好向你求助。设sis_isi 共有kik_iki个不同子串是合法括号串,
你只需要告诉小 Q 所有i×kii \times k_{i}i×ki
的异或和,即:
(1×k1)xor⁡(2×k2)xor⁡(3×k3)xor ⋯xor (n×kn)\left(1 \times k_{1}\right) \operatorname{xor}\left(2 \times k_{2}\right) \operatorname{xor}\left(3 \times k_{3}\right) \text { xor } \cdots \text { xor }\left(n \times k_{n}\right)(1×k1)xor(2×k2)xor(3×k3) xor  xor (n×kn)
其中 xor 是位异或运算。
输入描述:
第一行一个整数 n,表示树的大小。
第二行一个长为 n 的由’(’ 与’)’ 组成的括号串,第 i 个括号表示 i 号结点上的括号。
第三行包含 n− 1 个整数,第i (1≤i<n)个整数表示 i + 1 号结点的父亲编号 fi+1f_{i+1}fi+1
输出描述:
仅一行一个整数表示答案。
示例1
输入
5
(()()
1 1 2 2
输出
6
说明
树的形态如下图:
在这里插入图片描述
将根到 1 号结点的简单路径上的括号,按经过顺序排列所组成的字符串为 (,子串 是合法括号串的个数为 0。
将根到 2 号结点的简单路径上的括号,按经过顺序排列所组成的字符串为 ((,子 串是合法括号串的个数为 0。
将根到 3 号结点的简单路径上的括号,按经过顺序排列所组成的字符串为 (),子 串是合法括号串的个数为 1。
将根到 4 号结点的简单路径上的括号,按经过顺序排列所组成的字符串为 (((,子 串是合法括号串的个数为 0。
将根到 5 号结点的简单路径上的括号,按经过顺序排列所组成的字符串为 ((),子 串是合法括号串的个数为 1。
在这里插入图片描述

题解

这里不再单独呈现单链的暴力分,因为我们发现单链的思路可以完全适用于整棵树上

思考如果x这个点上的括号是右括号,那么它可能对答案进行贡献的前提就是从根到x这单独的一条链上前面至少还有一个多余的左括号,跟它进行匹配,那么它的值就会从前一个未能匹配的左括号的值转移+1。并且这个左括号一定是最远离根就是最接近于x的位置

那么我们就设dp[i]dp[i]dp[i]表示从根1到i位置为止的匹配成功的括号数,不管匹配成功的括号里面又有多少个成功的括号对,例如(()())(()())(()())到最后一个右括号时它的dp只有1
那么这中间多多搭配多出的成功匹配对就通过dfs往下传递就可以了

pre[i]pre[i]pre[i]表示与i无法匹配的距离i最近的一个左括号所在的位置


如果i本身是一个左括号就不可能与前面匹配成功,它的dp就是0,并且离它最近的左括号就是自己本身嘛!!
如果i是右括号,那么就要再次判断到它爸爸为止之前是否有多余的左括号与i匹配
如果有那么i就与记录下的它爸爸的最近的一个无法匹配的左括号位置进行匹配,即
pre[f[i]]pre[f[i]]pre[f[i]],那么它的括号匹配对就是与i匹配的左括号的父亲为止的匹配对再加1
那么转移方程式就出来了dp[u]=dp[f[pre[f[i]]]]+1dp[u]=dp[f[pre[f[i]]]]+1dp[u]=dp[f[pre[f[i]]]]+1

那么接下来就要转移pre[i]pre[i]pre[i],我们想一想如果i与某一个左括号匹配成功了,那么距离i最近的一个多余的左括号其实就是匹配成功的左括号的父亲所无法匹配的最近的左括号,转移方程式如下pre[i]=pre[f[pre[f[i]]]]pre[i]=pre[f[pre[f[i]]]]pre[i]=pre[f[pre[f[i]]]]

代码实现

#include <cstdio>
#include <vector>
using namespace std;
#define LL long long
#define MAXN 500005
vector < int > G[MAXN];
int n;
LL result;
int f[MAXN], tree[MAXN];
LL dp[MAXN], pre[MAXN];void dfs ( int u, LL sum ) {if ( tree[u] == '(' )pre[u] = u;else if ( f[u] && pre[f[u]] ) {dp[u] = dp[f[pre[f[u]]]] + 1;pre[u] = pre[f[pre[f[u]]]];}sum += dp[u];result ^= sum * u; for ( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];dfs ( v, sum );}
}int main() {scanf ( "%d\n", &n );for ( int i = 1;i <= n;i ++ )scanf ( "%c", &tree[i] );for ( int i = 2;i <= n;i ++ ) {scanf ( "%d", &f[i] );G[f[i]].push_back( i );}dfs ( 1, 0 );printf ( "%lld", result );return 0;
} 

T3:树上的数

题目

给定一个大小为 n 的树,它共有 n 个结点与 n − 1 条边,结点从 1 ∼ n 编号。初始时每个结点上都有一个 1 ∼ n 的数字,且每个 1 ∼ n 的数字都只在恰好一个结点上出现。
接下来你需要进行恰好n − 1 次删边操作,每次操作你需要选一条未被删去的边,此时这条边所连接的两个结点上的数字将会交换,然后这条边将被删去。
n − 1 次操作过后,所有的边都将被删去。此时,按数字从小到大的顺序,将数字1 ∼ n 所在的结点编号依次排列,就得到一个结点编号的排列PiP_iPi 。现在请你求出,在最优操作方案下能得到的字典序最小的 PiP_iPi
在这里插入图片描述
如上图,蓝圈中的数字 1 ∼ 5 一开始分别在结点 ② 、① 、③ 、⑤ 、④ 。按照 (1)(4)(3)(2)的顺序删去所有边,树变为下图。按数字顺序得到的结点编号排列为 ① ③ ④ ② ⑤ ,该排列是所有可能的结果中字典序最小的。
在这里插入图片描述
输入描述:
本题输 入包含多组测试数据。
第一行一个正整数 T,表示数据组数。
对于每组测试数据:
第一行一个整数 n,表示树的大小。
第二行 n 个整数,第 i(1≤i≤n)i(1\leq i\leq n)i1in个整数表示数字 i 初始时所在的结点编号。 接下来 n−1 行每行两个整数 x,y,表示一条连接 x 号结点与 y 号结点的边
输出描述:
对于每组测试数据,输出一行共 n 个用空格隔开的整数,表示最优操作方案下所 能得到的字典序最小的 PiP_iPi
示例1
输入
4
5
2 1 3 5 4
1 3
1 4
2 4
4 5
5
3 4 2 1 5
1 2
2 3
3 4
4 5
5
1 2 5 3 4
1 2
1 3
1 4
1 5
10
1 2 3 4 5 7 8 9 10 6
1 2
1 3
1 4
1 5
5 6
6 7
7 8
8 9
9 10
输出
1 3 4 2 5
1 3 5 2 4
2 3 1 4 5
2 3 4 5 6 1 7 8 9 10
在这里插入图片描述
对于所有测试点:1≤T≤101\leq T \leq101T10,保证给出的是一个树

10pts暴力题解

暴力题解的话十分简单,因为n为10,我们就跑出每一种可能的删边顺序,一共是!(n−1)!(n-1)!(n1)再加上有T组数据最多也就是10,极限时间复杂度就是O(!n)O(!n)O(!n),对于10而言是可以卡过去的

代码实现

#include <cstdio>
#include <iostream>
using namespace std;
#define MAXN 2005
struct node {int u, v;node () {}node ( int U, int V ) {u = U;v = V;}
}edge[MAXN];
int T, n;
int num[MAXN], tree[MAXN], a[MAXN], b[MAXN], c[MAXN];
bool vis[MAXN];
string result;void dfs ( int x ) {if ( x == n ) {string str = "";for ( int i = 1;i <= n;i ++ ) {b[i] = tree[i];c[tree[i]] = i;}for ( int i = 1;i < n;i ++ )swap ( c[b[edge[a[i]].u]], c[b[edge[a[i]].v]] );for ( int i = 1;i <= n;i ++ )str += ( c[i] + '0' );if ( result == "" )result = str;elseresult = min ( result, str );return;}for ( int i = 1;i < n;i ++ )if ( ! vis[i] ) {vis[i] = 1;a[x] = i;dfs ( x + 1 );vis[i] = 0;}
}int main() {scanf ( "%d", &T );while ( T -- ) {scanf ( "%d", &n );for ( int i = 1;i <= n;i ++ ) {scanf ( "%d", &num[i] );tree[num[i]] = i;}for ( int i = 1;i < n;i ++ ) {int x, y;scanf ( "%d %d", &x, &y );edge[i] = ( node ( x, y ) );}if ( n <= 10 ) {result = "";dfs ( 1 );for ( int i = 0;i < n;i ++ )printf ( "%d ", result[i] - '0' );printf ( "\n" );}}return 0;
}

25pts菊花图题解

对于菊花图也就是长成如下的样子,数据范围的解释也给的很明确就算考场上不知道什么是菊花图也应该画得出来这种图
在这里插入图片描述
都能想到肯定是依次满足1,2,3…的要求,尽量把1送到1节点,这样才能保证字典序最小
其实根根本没有什么特殊作用,它就是起一个中转站的感觉,两个叶子进行交换的时候路过了罢了
对于菊花图有三种移动方式
1、根移动到某一个叶子节点
2、某一个叶子节点移动到根,那么就必须要求这一条边是所有边中最后一条被删掉的
3、两个叶子之间的移动
我们考虑有哪种情况是不合法的移动,很显然
1、如果根想移动到某一个叶子节点,而那个叶子节点也想移动到根,这就要求这条边是最后一条被删的边,并且删完其他边后,根上面的值没有动过,肯定是满足不了的!!!
2、两个叶子之间想相互转移也是实现不了的,只能满足其中一个
所以我们就要求转移后删的边形成一个环,怎么做呢??并查集!!
如果i与j本身就是一个集合,就不能把j连向i,这样会提前形成环

这种情况连边都可以直接不管了,比暴力还来得容易

代码实现

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXN 2005
int T, n;
int num[MAXN], tree[MAXN];
int f[MAXN], ans[MAXN];
bool vis[MAXN];void makeSet () {for ( int i = 1;i <= n;i ++ )f[i] = i;
}
int findSet ( int x ) {if ( x != f[x] )f[x] = findSet ( f[x] );return f[x];
}int main() {scanf ( "%d", &T );while ( T -- ) {scanf ( "%d", &n );for ( int i = 1;i <= n;i ++ ) {vis[i] = 0;scanf ( "%d", &num[i] );tree[num[i]] = i;}for ( int i = 1;i < n;i ++ ) {int x, y;scanf ( "%d %d", &x, &y );}makeSet();for ( int i = 1;i < n;i ++ ) {int now = 0x7f7f7f7f;for ( int j = 1;j <= n;j ++ ) {if ( ! vis[j] && findSet ( j ) != num[i] ) {now = min ( now, j );}}ans[i] = now;vis[now] = 1;f[num[i]] = now;}for ( int i = 1;i < n;i ++ )printf ( "%d ", ans[i] );for ( int i = 1;i <= n;i ++ )if ( ! vis[i] ) {printf ( "%d\n", i );break;}}return 0;
}

25pts单链题解

单链的话,也比较好想,实现也。。。
借用菊花图的思想,肯定也是1,2,3…这样依次满足下去,但是单链就意味着他们是在同一条路上进行操作,就会有不同的方向,对于一个链上的点(除开头和尾),会有两条边,删边顺序不是先左后右就是先右后左,我们用1表示先右后左,2表示先左后右,0表示没限制都可以

对于接下来的操作,我们思考如果点x要往左转移到y,那么这一路上要满足的性质就是,对于x这个点就必须先左后右地转移,否则x可能往右转移走了,y就必须先左后右,这样当最后一次交换y与y的右边的时候,x就可以被锁死在y而不被转移掉,这一路上的点都必须为0无限制或者1,这样从右往左才能依次像过安检一样把x传过去。。。对于一个点右移与上面的思路是一样的这里不再赘述

最后单独处理一下头和尾就不对他两个进行特殊打标,反正都只有一条边就没有所谓的先后关系

代码实现

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXN 2005
vector < int > g[MAXN];
int T, n;
int num[MAXN], tree[MAXN];
int vis[MAXN];
int d[MAXN], f[MAXN], ans[MAXN], pus[MAXN];void build ( int u, int x, int fa ) {pus[x] = u;num[tree[u]] = x;for ( int i = 0;i < g[u].size();i ++ ) {int v = g[u][i];if ( v == fa )continue;build ( v, x + 1, u );}
}int main() {scanf ( "%d", &T );while ( T -- ) {scanf ( "%d", &n );for ( int i = 1;i <= n;i ++ ) {d[i] = 0;vis[i] = 0;pus[i] = 0;g[i].clear();scanf ( "%d", &num[i] );tree[num[i]] = i;}for ( int i = 1;i < n;i ++ ) {int x, y;scanf ( "%d %d", &x, &y );d[x] ++;d[y] ++;g[x].push_back( y );g[y].push_back( x );}int root;for ( int i = n;i >= 1;i -- )if ( d[i] == 1 )root = i;build ( root, 1, 0 );for ( int i = 1;i <= n;i ++ ) {int now = 0x7f7f7f7f, idx;if ( ! vis[num[i]] || vis[num[i]] == 2 ) {for ( int j = num[i] - 1;j >= 1;j -- ) {if ( ! vis[j] || vis[j] == 2 ) {if ( pus[j] < now ) {now = pus[j];idx = j;}}if ( vis[j] == 2 )break;}}if ( ! vis[num[i]] || vis[num[i]] == 1 ) {for ( int j = num[i] + 1;j <= n;j ++ ) {if ( ! vis[j] || vis[j] == 1 ) {if ( pus[j] < now ) {now = pus[j];idx = j;}}if ( vis[j] == 1 )break;}}ans[i] = now;if ( idx < num[i] ) {if ( num[i] != 1 && num[i] != n )vis[num[i]] = 2;if ( idx != 1 && idx != n )vis[idx] = 2;for ( int j = idx + 1;j < num[i];j ++ )vis[j] = 1;}else {if ( num[i] != 1 && num[i] != n )vis[num[i]] = 1;if ( idx != 1 && idx != n )vis[idx] = 1;for ( int j = idx - 1;j > num[i];j -- )vis[j] = 2;}}for ( int i = 1;i < n;i ++ )printf ( "%d ", ans[i] );printf ( "%d\n", ans[n] );continue;}return 0;
}

把这三个部分的代码进行整合,就能达到60的高分了
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用PerfView监测.NET程序性能(四):折叠,过滤和时间范围选择

在上一篇文章使用PerfView监测.NET程序性能&#xff08;三&#xff09;&#xff1a;分组中&#xff0c;我们使用了Perfview的分组功能。分组功能旨在对某些函数按照某个格式进行分组&#xff0c;以减少视图中的各种无关函数的数量。但仅有分组还不够&#xff0c;有时我们想将一…

带旋treap概念及模板,带例题:普通平衡树

带旋Treap二叉查找树BST(Binary Search Tree)定义Treap定义模板合集&#xff08;均为O(logn)O(logn)O(logn)&#xff09;push_up模板旋转模板插入模板删除模板查找前驱模板查找后驱模板查找键值key模板查找节点的修正值rank模板PS&#xff1a;rd的比较问题例题&#xff1a;普通…

微服务系列实践 .NET CORE

从事这个行业转眼已经6年了&#xff0c;从当初刚毕业的在北京朝八晚十&#xff0c;从二环到五环&#xff0c;仍每天精力充沛的小愤青&#xff1b;再到深圳一点一滴的辛勤在软件行业的耕种&#xff0c;从当初单体应用架构到现在微服务架构的经历&#xff0c;回想起来自己的收获倒…

P2607 [ZJOI2008]骑士

P2607 [ZJOI2008]骑士 题意&#xff1a; n个点n个边&#xff0c;每个点都有权值&#xff0c;相邻的点不能同时选择&#xff0c;问如何选择能使得权值最大 题解&#xff1a; 这个题很有P1352 没有上司的舞会这个题的感觉&#xff0c;唯一的区别是那个题保证是树&#xff0c;…

模板:线段树优化建图

前言 百川到海&#xff0c;天下归一 解析 线段树优化建图是用于对一个区间的点连边时的优化方法 建一棵in树一棵出树分别往上和下指即可 大概长这样 &#xff08;pia的洛谷的照片&#xff09; 建树 正常动态开点即可 void build(int &k,int l,int r){tr[ktot](tree){0…

[非旋平衡树]fhq_treap概念及模板,例题:普通平衡树,文艺线段树

文章目录概念全套模板push_up模板split拆树模板(按权值拆)split拆树模板(按个数拆)merge合并模板&#xff08;地址版&#xff09;merge合并模板&#xff08;带返回根&#xff09;区间模板insert插入模板delete删除模板find_kth找第k大模板get_rank找排名模板pre找前驱模板suf找…

surging 微服务引擎 1.0 正式发布

surging 是一个分布式微服务引擎,提供高性能RPC远程服务调用&#xff0c;服务引擎支持http、TCP、WS、Mqtt协议,采用Zookeeper、Consul作为surging服务的注册中心&#xff0c;集成了哈希一致性&#xff0c;随机&#xff0c;轮询、压力最小优先作为负载均衡的算法&#xff0c;底…

YBTOJ:彩色圆环

文章目录前言题目描述InputOutputSample InputSample Output解析代码前言 尽信书&#xff0c;则不如无书 题目描述 Input 仅有一行&#xff0c;该行给出依次两个正整数N, M&#xff0c;分别表示宝石的个数和宝石在变化时可能变成的颜色种类数。 Output 应仅有一行&#xff0…

【2019CSP-J 普及组题解】数字游戏(number),公交换乘(transfer),纪念品(souvenir),加工领奖(work) CSP普及游记

文章目录T1&#xff1a;数字游戏题目CODET2&#xff1a;公交换乘题目CODET3&#xff1a;纪念品题目题解CODET4&#xff1a;加工领奖题目题解CODE关于普及组的想法&游记T1&#xff1a;数字游戏 题目 小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串来玩数字游戏&…

搭建基于Docker社区版的Kubernetes本地集群

Kubernetes的本地集群搭建是一件颇费苦心的活&#xff0c;网上有各种参考资源&#xff0c;由于版本和容器的不断发展&#xff0c;搭建的方式也是各不相同&#xff0c;这里基于Docker CE的18.09.0版本&#xff0c;在Mac OS、Win10下分别搭建了一次。一、Mac OS下搭建安装Docker …

Infinite Tree

Infinite Tree 题意&#xff1a; 题解&#xff1a; 参考博客 看了好一阵子才明白。。。emm。 我们先按照题意画出一部分树 我们先不考虑复杂度&#xff0c;这题应该怎么做&#xff1f; 题目给了每个点的权值w[i]&#xff0c;问一个点到所有的节点路径长度*点权之和最小是多少…

IdentityServer4-从数据库获取User登录并对Claims授权验证(五)

本节将在第四节基础上介绍如何实现IdentityServer4从数据库获取User进行验证&#xff0c;并对Claim进行权限设置。一、新建Web API资源服务&#xff0c;命名为ResourceAPI&#xff08;1&#xff09;新建API项目&#xff0c;用来进行user的身份验证服务。&#xff08;2&#xff…

周末狂欢赛1(玩游戏/Game,函数,JOIOI王国)

狂欢1T1&#xff1a;玩游戏 / Game题目题解代码实现T2&#xff1a;函数题目题解代码实现T3&#xff1a;JOIOI王国题目题解代码实现T1&#xff1a;玩游戏 / Game 题目 ljcc 和他的学妹在玩游戏&#xff0c;这个游戏共有 n 轮&#xff0c;在第 i 轮获胜会获得 i 分&#xff0c;…

用ABP只要加人即可马上加快项目进展(二) - 分工篇 - BDD实战篇 - .NET Core里跑Specflow...

这是<如何用ABP框架快速完成项目 >系列中的一篇文章。BDD很赞&#xff01;比TDD先进很多&#xff0c;能够大大提高编码效率。上一篇文章说了如何在.NET Core里安装Specflow. 然而文章成果只到了hello world级别。要想真的和实际业务结合&#xff0c;比如要能够IOC new cl…

【做题记录】CodeForces 做题记录

链接放的是洛谷上的链接&#xff0c;难度就是 CF 上的评分。 <details><summary>$\texttt{solution}$</summary></details> CF10D LCIS 难度&#xff1a;\(\tt{2800}\) 求两个串的最长公共上升子序列。\(n\le 500\) $\texttt{solution}$ 严重虚高题&am…

周末狂欢赛2(冒泡排序,概率充电器,不勤劳的图书管理员)

狂欢2T1&#xff1a;冒泡排序题目题解CODET2&#xff1a;概率充电器题目题解CODET3&#xff1a;不勤劳的图书管理员题目题解CODE我不这么认为。。。。 T1&#xff1a;冒泡排序 题目 下面是一段实现冒泡排序算法的 C代码&#xff1a; for(int i1; i<n; i)for(int j1; j&l…

P5659-[CSP-S2019]树上的数【贪心】

正题 题目链接:https://www.luogu.com.cn/problem/P5659 题目大意 给出nnn个点的一棵树&#xff0c;每个节点上有一个数字&#xff0c;你每次可以选择一条边删除然后交换连接的两个点的数字&#xff0c;在删完所有数字后设pip_ipi​表示数字iii所在节点编号&#xff0c;要求使…

YBTOJ洛谷P3195:玩具装箱(斜率优化dp)

传送门 文章目录前言解析代码前言 斜率优化dp&#xff0c;就是利用斜率优化的dp &#xff08;逃&#xff09; 解析 第一道斜优的题 分析题目 设sumisum_isumi​为1-i的c的前缀和 容易写出dp转移式&#xff1a; dpimin(dpj(sumi−sumji−j−1−L)2)dp_imin(dp_j(sum_i-sum_ji-…

01.微服务系列介绍

微服务系列实践 .NET CORE在开始之前呢&#xff0c;还是得废话一下&#xff0c;毕竟还是需要介绍一下这个系列我们要实现什么样的一套服务架构&#xff0c;也让大家能初步的有一个了解&#xff0c;后续实践起来也有一个完整的概念&#xff0c;相对也会容易的多。互联网架构演变…

Walker

Walker 题意&#xff1a; 一个区间[0,n]&#xff0c;区间上有两个点&#xff0c;坐标分别是pos1&#xff0c;pos2&#xff0c;速度分别是v1&#xff0c;v2&#xff0c;这两个点是在移动&#xff0c;可以随时改变移动方向&#xff0c;问当区间的每一块均被一个点或两个点移动覆…