CSP-J 2020题解

本次考试还是很有用的,至少把我浇了一盆冷水。

当使用民间数据自测的时候,我就自闭了。

估分是320,但有些比较低级的错误直接少掉80。

而且这套题应该上350才正常吧,也不是像平时训练一样难。

主要是平时的时候太依赖于评测机了,小错误就都没注意,我认为在平时训练当中就应该一次成型,因为考试只有一次提交机会。

基础概念也需要搞清楚,比如运算优先级等等。

心态也要调整好。就这次考试而言,我的心态是极差的。多在考试之前鼓励下自己。可能就会好些吧!

调整心态,继续努力,把自己当做起跑线上的人,路还很长,我们还会继续!!

不多说了,上题解

T1 优秀的拆分

题目描述

一般来说,一个正整数可以拆分成若干个正整数的和。

例如,\(1=1\),\(10=1+2+3+4\) 等。对于正整数\(n\)的一种特定拆分,我们称它为“优秀的”,当且仅当在这种拆分下,\(n\)被分解为了若干个不同的\(2\)的正整数次幂。注意,一个数\(x\)能被表示成\(2\)的正整数次幂,当且仅当\(x\)能通过正整数个\(2\)相乘在一起得到。

例如,\(10=8+2=2^3+2^1\)是一个优秀的拆分。但是,\(7=4+2+1=2^2+2^1+2^0\)就不是一个优秀的拆分,因为\(1\)不是\(2\)的正整数次幂。

现在,给定正整数\(n\),你需要判断这个数的所有拆分中,是否存在优秀的拆分。若存在,请你给出具体的拆分方案。

输入格式

输入只有一行,一个整数\(n\),代表需要判断的数。

输出格式

如果这个数的所有拆分中,存在优秀的拆分。那么,你需要从大到小输出这个拆分中的每一个数,相邻两个数之间用一个空格隔开。可以证明,在规定了拆分数字的顺序后,该拆分方案是唯一的。

若不存在优秀的拆分,输出 -1。

输入输出样例

输入 #1

6

输出 #1

4 2

输入 #2

7

输出 #2

-1

说明/提示

样例 1 解释

\(6=4+2=2^2+2^1\)是一个优秀的拆分。注意,\(6=2+2+2\)不是一个优秀的拆分,因为拆分成的\(3\)个数不满足每个数互不相同。

数据规模与约定

对于\(20\%\)的数据,\(n \le 10\)。

对于另外\(20\%\)的数据,保证\(n\)为奇数。

对于另外\(20%\)的数据,保证\(n\)为\(2\)的正整数次幂。

对于\(80\%\)的数据,\(n \le 1024\)。

对于\(100\%\)的数据,\(1 \le n \le 1 \times 10^7\)。

思路

简单,倒着枚举二的正整数次幂即可。

C++代码

#include <queue>
#include <cstdio>
using namespace std;
queue<int> q;
int n;
int main() {
scanf("%d", &n);
for(int i = 30; i >= 1; i--) {
int now = (1 << i);
if(now <= n) {
n -= now;
q.push(now);
}
}
if(n != 0)
printf("-1");
else
while(!q.empty()) {
printf("%d ", q.front());
q.pop();
}
return 0;
}

T2 直播获奖

题目描述

NOI2130 即将举行。为了增加观赏性,CCF 决定逐一评出每个选手的成绩,并直播即时的获奖分数线。本次竞赛的获奖率为\(w\%\),即当前排名前\(w\%\)的选手的最低成绩就是即时的分数线。

更具体地,若当前已评出了\(p\)个选手的成绩,则当前计划获奖人数为\(\max(1, \lfloor p * w \%\rfloor)\),其中\(w\)是获奖百分比,\(\lfloor x \rfloor\)表示对\(x\)向下取整,\(\max(x,y)\)表示\(x\)和\(y\)中较大的数。如有选手成绩相同,则所有成绩并列的选手都能获奖,因此实际获奖人数可能比计划中多。

作为评测组的技术人员,请你帮 CCF 写一个直播程序。

输入格式

第一行有两个整数\(n, w\)。分别代表选手总数与获奖率。

第二行有\(n\)个整数,依次代表逐一评出的选手成绩。

输出格式

只有一行,包含\(n\)个非负整数,依次代表选手成绩逐一评出后,即时的获奖分数线。相邻两个整数间用一个空格分隔。

输入输出样例

输入 #1

10 60
200 300 400 500 600 600 0 300 200 100

输出 #1

200 300 400 400 400 500 400 400 300 300

输入 #2

10 30
100 100 600 100 100 100 100 100 100 100

输出 #2

100 100 600 600 600 600 100 100 100 100

说明/提示

样例 1 解释

数据规模与约定

对于所有测试点,每个选手的成绩均为不超过\(600\)的非负整数,获奖百分比\(w\)是一个正整数且\(1 \le w \le 99\)。

提示

在计算计划获奖人数时,如用浮点类型的变量(如 C/C++ 中的 float 、 double,Pascal 中的 real 、 double 、 extended 等)存储获奖比例 w%w%,则计算\(5 \times 60\%\)时的结果可能为\(3.000001\),也可能为\(2.999999\),向下取整后的结果不确定。因此,建议仅使用整型变量,以计算出准确值。

思路

使用一个大根堆与一个小根堆来模拟。

大根堆来储存分数线以下的分数。

小根堆来储存分数线以上的分数。

模拟分数线的波动即可。

C++代码

#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 1e5 + 5;
priority_queue<int, vector<int>, greater<int> > q1;
priority_queue<int> q2;
int a[MAXN];
int n, w;
int main() {
scanf("%d %d", &n, &w);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
int id = 1;
q1.push(a[1]);
printf("%d ", a[1]);
for(int i = 2; i <= n; i++) {
int now = i * w / 100;
if(a[i] > q1.top()) {
q1.push(a[i]);
int k = q1.top();
q2.push(k);
q1.pop();
}
else {
q2.push(a[i]);
}
if(now > id) {
id = now;
int k = q2.top(); q2.pop();
q1.push(k);
}
printf("%d ", q1.top());
}
return 0;
}

T3 表达式

题目描述

小 C 热衷于学习数理逻辑。有一天,他发现了一种特别的逻辑表达式。在这种逻辑表达式中,所有操作数都是变量,且它们的取值只能为\(0\)或 \(1\),运算从左往右进行。如果表达式中有括号,则先计算括号内的子表达式的值。特别的,这种表达式有且仅有以下几种运算:

  1. 与运算:a & b。当且仅当\(a\)和\(b\)的值都为\(1\)时,该表达式的值为\(1\)。其余情况该表达式的值为\(0\)。
  2. 或运算:a | b。当且仅当\(a\)和\(b\)的值都为\(0\)时,该表达式的值为\(0\)。其余情况该表达式的值为\(1\)。
  3. 取反运算:!a。当且仅当\(a\)的值为\(0\)时,该表达式的值为\(1\)。其余情况该表达式的值为\(0\)。

小 C 想知道,给定一个逻辑表达式和其中每一个操作数的初始取值后,再取反某一个操作数的值时,原表达式的值为多少。

为了化简对表达式的处理,我们有如下约定:

表达式将采用后缀表达式的方式输入。

后缀表达式的定义如下:

  1. 如果\(E\)是一个操作数,则\(E\)的后缀表达式是它本身。
  2. 如果\(E\)是\(E_1~\texttt{op}~E\)形式的表达式,其中\(\texttt{op}\)是任何二元操作符,且优先级不高于\(E_1\)、\(E_2\)中括号外的操作符,则\(E\)的后缀式为 \(E_1' E_2' \texttt{op}\),其中\(E_1'\)、\(E_2'\)分别为\(E_1\)、\(E_2\)的后缀式。
  3. 如果\(E\)是\(E_1\)形式的表达式,则\(E_1\)的后缀式就是\(E\)的后缀式。

    同时为了方便,输入中:

与运算符(&)、或运算符(|)、取反运算符(!)的左右均有一个空格,但表达式末尾没有空格。

操作数由小写字母\(x\)与一个正整数拼接而成,正整数表示这个变量的下标。例如:x10,表示下标为\(10\)的变量\(x_{10}\)。数据保证每个变量在表达式中出现恰好一次。

输入格式

第一行包含一个字符串\(s\),表示上文描述的表达式。

第二行包含一个正整数\(n\),表示表达式中变量的数量。表达式中变量的下标为\(1,2, \cdots , n\)。

第三行包含\(n\)个整数,第\(i\)个整数表示变量\(x_i\)的初值。

第四行包含一个正整数\(q\),表示询问的个数。

接下来\(q\)行,每行一个正整数,表示需要取反的变量的下标。注意,每一个询问的修改都是临时的,即之前询问中的修改不会对后续的询问造成影响。

数据保证输入的表达式合法。变量的初值为\(0\)或\(1\)。

输出格式

输出一共有\(q\)行,每行一个\(0\)或\(1\),表示该询问下表达式的值。

输入输出样例

输入 #1

x1 x2 & x3 |
3
1 0 1
3
1
2
3

输出 #1

1
1
0

输入 #2

x1 ! x2 x4 | x3 x5 ! & & ! &
5
0 1 0 1 1
3
1
3
5

输出 #2

0
1
1

说明/提示

样例 1 解释

该后缀表达式的中缀表达式形式为\((x_1 \& x_2) | x_3\)。

对于第一次询问,将\(x_1\)的值取反。此时,三个操作数对应的赋值依次为\(0\),\(0\),\(1\)。原表达式的值为\((0\&0)|1=1\)。

对于第二次询问,将\(x_2\)的值取反。此时,三个操作数对应的赋值依次为\(1\),\(1\),\(1\)。原表达式的值为\((1\&1)|1=1\)。

对于第三次询问,将\(x_3\)的值取反。此时,三个操作数对应的赋值依次为\(1\),\(0\),\(0\)。原表达式的值为\((1\&0)|0=0\)。

样例 2 解释

该表达式的中缀表达式形式为\((!x_1)\&(!((x_2|x_4)\&(x_3\&(!x_5))))\)。

数据规模与约定

对于\(20\%\)的数据,表达式中有且仅有与运算(&)或者或运算(|)。

对于另外\(30\%\)的数据,\(|s| \le 1000\),\(q \le 1000\),\(n \le 1000\)。

对于另外\(20\%\)的数据,变量的初值全为\(0\)或全为\(1\)。

对于\(100\%\)的数据,\(1 \le |s| \le 1 \times 10^6\),\(1 \le q \le 1 \times 10^5\),\(2 \le n \le 1 \times 10^5\)。

其中,\(|s|\)表示字符串\(s\)的长度。

思路

首先对于仅有或运算和且运算的情况,不难想到可以骗分,再利用后缀表达式跑一遍暴力就可以骗到50分,时间复杂度为\(O(nq)\)。

这种做法可以优化吗?或运算和且运算都有两个数字进行运算,是不是很像一颗二叉树。而且这颗二叉树有一个特性:每个父节点都必有两个子节点。利用这一点,可以去看若改变这颗树上的某一个值,会不会对本次计算产生影响,进而推出是否会对整个结果产生影响,预处理一次时间复杂度为\(O(n)\),即便利这整棵树。总的来看加上后面的查询,时间复杂度为\(O(n+q)\)。

C++代码

#include <stack>
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
void Quick_Read(int &Number) {
Number = 0;
char c = getchar();
int op = 1;
while (c < '0' || c > '9') {
if (c == '-')
op = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
Number = (Number << 1) + (Number << 3) + c - 48;
c = getchar();
}
Number *= op;
}
const int MAXN = 1e6 + 5;
struct Node {
int Left_Child, Right_Child;
int Value, Index, Operator;
};
stack<int> s;
string c;
Node Tree[MAXN];
bool Alter[MAXN];
int Num[MAXN];
int len, n, q;
void calc(int x) {
if(Tree[x].Operator == -1) {
Alter[Tree[x].Index] = 1;
return;
}
if(!Tree[x].Operator)
calc(Tree[x].Left_Child);
else if(Tree[x].Operator == 1) {
int Left_Child = Tree[x].Left_Child;
int Right_Child = Tree[x].Right_Child;
if(Tree[Left_Child].Value + Tree[Right_Child].Value == 2) {
calc(Left_Child);
calc(Right_Child);
}
else if(Tree[Left_Child].Value)
calc(Right_Child);
else if(Tree[Right_Child].Value)
calc(Left_Child);
}
else {
int Left_Child = Tree[x].Left_Child;
int Right_Child = Tree[x].Right_Child;
if(Tree[Left_Child].Value + Tree[Right_Child].Value == 0) {
calc(Left_Child);
calc(Right_Child);
}
else if(!Tree[Left_Child].Value)
calc(Right_Child);
else if(!Tree[Right_Child].Value)
calc(Left_Child);
}
}
void Read() {
int A;
getline(cin, c);
Quick_Read(n);
for(int i = 1; i <= n; i++)
Quick_Read(Num[i]);
for(int i = 0; i < c.length(); i++) {
if(c[i] == 'x') {
int x = 0;
while(c[i + 1] <= '9' && c[i + 1] >= '0') {
x = x * 10 + c[i + 1] - 48;
i++;
}
len++;
Tree[len].Value = Num[x];
Tree[len].Index = x;
Tree[len].Operator = -1;
s.push(len);
continue;
}
if(c[i] == '!') {
len++;
Tree[len].Value = !Tree[s.top()].Value;
Tree[len].Left_Child = s.top(); s.pop();
Tree[len].Operator = 0;
s.push(len);
continue;
}
if(c[i] == '&') {
len++;
int Number1 = s.top(); s.pop();
int Number2 = s.top(); s.pop();
Tree[len].Value = Tree[Number1].Value & Tree[Number2].Value;
Tree[len].Operator = 1;
Tree[len].Left_Child = Number1;
Tree[len].Right_Child = Number2;
s.push(len);
continue;
}
if(c[i] == '|') {
len++;
int Number1 = s.top(); s.pop();
int Number2 = s.top(); s.pop();
Tree[len].Value = Tree[Number1].Value | Tree[Number2].Value;
Tree[len].Operator = 2;
Tree[len].Left_Child = Number1;
Tree[len].Right_Child = Number2;
s.push(len);
continue;
}
}
}
void Write() {
int A;
Quick_Read(q);
for(int i = 1; i <= q; i++) {
Quick_Read(A);
if(Alter[A])
printf("%d\n", !Tree[len].Value);
else
printf("%d\n", Tree[len].Value);
}
}
int main() {
Read();
calc(len);
Write();
return 0;
}

T4 方格取数

题目描述

设有\(n \times m\)的方格图,每个方格中都有一个整数。现有一只小熊,想从图的左上角走到右下角,每一步只能向上、向下或向右走一格,并且不能重复经过已经走过的方格,也不能走出边界。小熊会取走所有经过的方格中的整数,求它能取到的整数之和的最大值。

输入格式

第一行有两个整数\(n, m\)。

接下来\(n\)行每行\(m\)个整数,依次代表每个方格中的整数。

输出格式

一个整数,表示小熊能取到的整数之和的最大值。

输入输出样例

输入 #1

3 4
1 -1 3 2
2 -1 4 -1
-2 2 -3 -1

输出 #1

9

输入 #2

2 5
-1 -1 -3 -2 -7
-2 -1 -4 -1 -2

输出 #2

-10

说明/提示

按上述走法,取到的数之和为\(1 + 2 + (-1) + 4 + 3 + 2 + (-1) + (-1) = 9\),可以证明为最大值。

注意,上述走法是错误的,因为第\(2\)行第\(2\)列的方格走过了两次,而根据题意,不能重复经过已经走过的方格。

另外,上述走法也是错误的,因为没有走到右下角的终点。

数据规模与约定

对于\(20\%\)的数据,\(n, m \le 5\)。

对于\(40\%\)的数据,\(n, m \le 50\)。

对于\(70\%\)的数据,\(n, m \le 300\)。

对于\(100\%\)的数据,\(1 \le n,m \le 10^3\)。方格中整数的绝对值不超过\(10^4\)。

思路

看到这道题的时候想到的是用最短路。

但是仔细想想,若用Dijkstra有正边有负边,不可以用。若用SPFA,回有环。若强行用分层图来维护的话,时间复杂度就为\(O(n^2mlog(n^2m))\),肯定会超时。

于是在考场上就想了一个70分的dp带前缀和优化,时间复杂度为\(O(n^2m)\) 。

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1e3 + 5;
int dp[MAXN][MAXN];
int dist[MAXN];
int a[MAXN][MAXN];
int n, m;
int main() {
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i; j++)
dp[1][i] += a[j][1];
}
for(int i = 2; i <= m; i++) {
dist[1] = a[1][i];
for(int j = 2; j <= n; j++)
dist[j] = dist[j - 1] + a[j][i];
for(int j = 1; j <= n; j++)
dp[i][j] = dp[i - 1][j] + a[j][i];
for(int j = 1; j <= n; j++) {
for(int k = 1; k <= n; k++) {
dp[i][j] = max(dp[i][j], dp[i - 1][k] + dist[max(j, k)] - dist[min(j, k) - 1]);
}
}
}
printf("%d", dp[m][n]);
return 0;
}

(顺便说一句,考试时宏定义Max和Min没加括号,直接导致这题爆零,正确的宏定义应为:#define Min(a, b) ((a) < (b) ? (a) : (b))。)

如何来优化呢?

定义两个dp,一个记录从上往下走的答案,一个记录从下往上走的答案。

状态转移方程:

  1. 只可以向右走,而不能向左走,就是上一层的路径转换到本层即可

    \(f[i][j][1]=f[i][j][0]=\max(f[i-1][j][1],f[i-1][j][0])+a[i][j]\)
  2. 向下走

    \(f[i][j][1]=max(f[i][j][1],f[i][j−1][1]+a[i][j])\)
  3. 向下走

    \(f[i][j][0]=max(f[i][j][0],f[i][j+1][0]+a[i][j])\)

C++代码

#include <cstdio>
#define LL long long
#define INF 1e17
#define Max(a, b) ((a) > (b) ? (a) : (b))
void Quick_Read(LL &Number) {
Number = 0;
char c = getchar();
LL op = 1;
while (c < '0' || c > '9') {
if (c == '-')
op = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
Number = (Number << 1) + (Number << 3) + c - 48;
c = getchar();
}
Number *= op;
}
const LL MAXN = 1e3 + 5;
LL Map[MAXN][MAXN], dp[MAXN][MAXN][2];
LL n, m;
int main() {
Quick_Read(n);
Quick_Read(m);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
Quick_Read(Map[i][j]);
dp[i][j][0] = dp[i][j][1] = -INF;
}
}
dp[1][1][0] = dp[1][1][1] = Map[1][1];
for(int i = 2; i <= n; i++)
dp[i][1][1] = dp[i - 1][1][1] + Map[i][1];
for(int j = 2; j <= m; j++) {
dp[1][j][1] = dp[1][j][0] = Max(dp[1][j - 1][0], dp[1][j - 1][1]) + Map[1][j];
for(int i = 2; i <= n; i++) {
dp[i][j][0] = Max(dp[i][j - 1][0], dp[i][j - 1][1]) + Map[i][j];
dp[i][j][1] = Max(dp[i][j][0], dp[i - 1][j][1] + Map[i][j]);
}
for(int i = n - 1; i > 0; i--)
dp[i][j][0] = Max(dp[i][j][0], dp[i + 1][j][0] + Map[i][j]);
}
printf("%lld", Max(dp[n][m][0], dp[n][m][1]));
return 0;
}

CSP-J 2020题解的更多相关文章

  1. M-SOLUTIONS Programming Contest 2020 题解

    M-SOLUTIONS Programming Contest 2020 题解 目录 M-SOLUTIONS Programming Contest 2020 题解 A - Kyu in AtCode ...

  2. CSP J/S 初赛总结

    CSP J/S 初赛总结 2021/9/19 19:29 用官方答案估计 J 涂卡的时候唯一的一支 2B 铅笔坏了,只能用笔芯一个个涂 选择 \(-6\ pts\) 判断 \(-3\ pts\) 回答 ...

  3. CSP-S 2020 题解

    赛后我重拳出击,赛场上我却爆零.哎. 题解本人口胡.有错请各位大佬们指出. A. 儒略日 这题是大型模拟题. 介绍两种写法:一种代码量致死(赛 场 自 闭),一种是非常好写的. 写法 1 我在赛场的思 ...

  4. leetcode题解:Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构造二叉树)

    题目: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume ...

  5. 【游记】CSP J/S 2019 游记

    J 组 \(2:30\)开始, \(2:13\)还在酒店的我看了看手表...飞奔考场. T1 数字游戏 秒切. 下午某中学某大佬说可用线性基(%) T2 公交换乘 用单调队列思想,秒切. T3 纪念品 ...

  6. 福建工程学院第十四届ACM校赛J题题解

    第六集,想不到你这个浓眉大眼的都叛变革命了 题意: 给你两个只包含01的字符串S和T,问你在允许一次错误的情况下,T是否能成为S的子串 思路: 这个问题的解法挺多,我是用fft匹配的,也比较简单,针对 ...

  7. atcoder Keyence Programming Contest 2020 题解

    比赛地址 A 题意:给一个\(n*m\)的初始为白色的矩阵,一次操作可以将一行或一列染成 黑色,问至少染出\(k\)个黑点的最少操作次数. \(n\),\(m\)<=100,\(k\)<= ...

  8. 【题解】【直方图】【Leetcode】Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  9. CSP J/S 2019受虐记

    一枚蒟蒻的游记~ 提高组DAY1 不是说每场考试都有一道签到题吗 那我tm读了三遍题硬是没找到一道水题是怎么回事(是我太弱了吗) 没办法,硬着头皮做T1 暴力写法...期望得分30pts 于是...在 ...

随机推荐

  1. JetBrains-CLion永久激活教程

    前言 JetBrains Clion 是一款专为 C/C++ 开发所设计的跨平台 IDE.本文适用 JetBrains CLion v2019.3/3.1/3.2/3.3 永久激活,附破解补丁和激活码 ...

  2. STM32芯片型号的命名规则

    意法半导体已经推出STM32基本型系列.增强型系列.USB基本型系列.增强型系列:新系列产品沿用增强型系列的72MHz处理频率.内存包括64KB到256KB闪存和20KB到64KB嵌入式SRAM.新系 ...

  3. 【Azure微服务 Service Fabric 】因证书过期导致Service Fabric集群挂掉(升级无法完成,节点不可用)

    问题描述 创建Service Fabric时,证书在整个集群中是非常重要的部分,有着用户身份验证,节点之间通信,SF升级时的身份及授权认证等功能.如果证书过期则会导致节点受到影响集群无法正常工作. 当 ...

  4. eclipse 开发常见问题集锦

    问题1: eclipse导入外部项目,中文显示乱码(如下图) 方案:项目名-->右键属性-->如下图: 问题2: jsp/html页面eclipse双击打开,代码在工作区不显示(如下图:) ...

  5. Retrofit学习

    ---恢复内容开始--- public class MainActivity extends AppCompatActivity { @Override protected void onCreate ...

  6. STM32入门系列-学习STM32要掌握的内容

    STM32芯片架构 STM32F103系列芯片的系统架构如下: STM32芯片基于ARM公司的Cortex-M3内核,由ST公司设计生产,内核与总线矩阵之间有I(指令).S(系统).D(数据)三条信号 ...

  7. Learn day8 re正则表达式\search函数\反射\tcp发送消息(循环)\udp发送消息

    1.匹配单个字符 # ### 正则表达式 - 单个字符匹配 import re ''' findall 把匹配的结果直接返回到列表中 lst = re.findall("正则表达式" ...

  8. Jetbrains全系列产品 2020最新激活方法 (即时更新)

    即时更新:http://idea.itmatu.com/key Jetbrains全系列产品 2020最新激活方法 JMFL04QVQA-eyJsaWNlbnNlSWQiOiJKTUZMMDRRVlF ...

  9. Linux__用户用户组和权限

    用户用户组和权限 useradd +用户名, 添加这个用户 userdel +用户名, 删除这个用户(有残留 ) userdel -r +用户名, 彻底删除这个用户 groupadd +组名 ,添加这 ...

  10. 「SHOI2015」超能粒子炮・改

    「SHOI2015」超能粒子炮・改 给你\(T\)组询问,每组询问给定参数\(n,k\),计算\(\sum\limits_{i=0}^k\dbinom{n}{i}\). \(T\leq10^5,n,k ...