小雨的三角形
链接:https://ac.nowcoder.com/acm/contest/12196/B
来源:牛客网
题目描述
小雨手上有一个填满了数字的三角形。这个三角形一共有 nn 层,其中第 ii 层共有 ii个数,且第 11 个数和第 ii 个数均为 ii 。其余的数中,第 jj 个数是上一层中第 j-1j−1 个数和第 jj 个数的和。小雨想知道这个三角形第 xx 层到第 yy 层所有数的和,一共有 mm 个询问。
输入描述:
第一行两个正整数 n,mn,m,表示这个三角形的层数和询问个数。
接下来 mm 行,每行两个正整数 x,yx,y,表示一次询问。
输出描述:
输出共 mm 行,每行一个整数,表示一组询问的答案,对 10^9 + 710
9
+7 取模。
示例1
输入
复制
5 3
1 2
1 5
3 5
输出
复制
5
83
78
说明
画出这个三角形:
1
2 2
3 4 3
4 7 7 4
5 11 14 11 5
第 1 \sim 21∼2 层的和为 1 + 2 + 2 = 51+2+2=5 。
第 1 \sim 51∼5 层的和为 1 + 2 + 2 + 3 + 4 + 3 + 4 + 7 + 7+ 4 + 5 + 11 + 14 + 11 + 5 = 831+2+2+3+4+3+4+7+7+4+5+11+14+11+5=83 。
第 3 \sim 53∼5 层的和为 3 + 4 + 3 + 4 + 7 + 7+ 4 + 5 + 11 + 14 + 11 + 5 = 783+4+3+4+7+7+4+5+11+14+11+5=78 。
备注:
1 \leq n \leq 10^3,1 \leq m \leq 10^3,1 \leq x \leq y \leq n1≤n≤10
3
,1≤m≤10
3
,1≤x≤y≤n
有差的都得先取余数再加上取余数
/* _
_ooOoo_
o8888888o
88" . "88
(| -_- |)
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||_ \
| | \\\ - /'| | |
| \_| `\`---'// |_/ |
\ .-\__ `-. -'__/-. /
___`. .' /--.--\ `. .'___
."" '< `.___\_<|>_/___.' _> \"".
| | : `- \`. ;`. _/; .'/ / .' ; |
\ \ `-. \_\_`. _.'_/_/ -' _.' /
===========`-.`___`-.__\ \___ /__.-'_.'_.-'================
Please give me AC.
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
//#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
//using namespace __gnu_cxx;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl "\n"
//#define x first
//#define y second
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
inline void print(INT x) {
if (x < 0) { putchar('-'); x = -x; }
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
const int N = 1e3 + 10;
const int M = 3 * N;
const int mod = 1e9 + 7;
const int PP = 131;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
int n, m;
int a[N][N];
int s[N];
signed main(){
gt(n), gt(m);
for (int i = 1; i <= n; i ++){
int sum = 0;
for (int j = 1; j <= i; j ++){
if (j == 1 || j == i) a[i][j] = i;
else{
a[i][j] = a[i - 1][j] % mod + a[i - 1][j] % mod;
a[i][j] %= mod;
}
sum += a[i][j];
sum %= mod;
}
s[i] = s[i - 1] + sum;
s[i] %= mod;
}
while(m --){
int a, b;
gt(a), gt(b);
// if (b < a) cout << "0"
cout << ((s[b] - s[a - 1]) % mod + mod) % mod << endl;
//cout << endl;
}
return 0;
}
小石的海岛之旅
链接:https://ac.nowcoder.com/acm/contest/12196/C
来源:牛客网
题目描述
暑假到了,小石和小雨到海岛上玩。
从水平方向看海岛可以看成 nn个小块,每一个小块都有一个高度h_ih
i
,
水位一开始为 00,随着水位的上升,海岛分成了若干块。
现在有 mm 个询问,求当水位为a_ia
i
时,海岛会分成多少块。
输入描述:
第一行输入两个正整数n,mn,m,分别表示海岛小块个数和询问个数。
第二行输入 nn 个整数 h_ih
i
,表示每一块的高度。
第三行输入 mm个整数 a_ia
i
,表示每一个询问,保证输入的 a_ia
i
单调递增。
输出描述:
共 mm 行,分别对应 mm 个询问的答案。
示例1
输入
复制
7 3
1 2 3 1 2 1 3
1 2 3
输出
复制
3
2
0
说明
当水位高度为 1 时,岛屿被分成 3 块,2 3;2;3
当水位高度为 2 时,岛屿被分成 2 块:3;3 。
当水位高度为 3 时,岛屿全部被淹没,剩余 0 块 。
备注:
1 \leq n,m \leq 10^3,1 \leq h_i \leq 10^9,1 \leq a_i < a_{i + 1} \leq 10^91≤n,m≤10
3
,1≤h
i
≤10
9
,1≤a
i
<a
i+1
≤10
9
暴力双指针即可
#include<iostream>
using namespace std;
const int N = 1010;
int a[N];
int n, m;
int x;
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i ++) scanf("%d", &a[i]);
while(m--)
{
int res = 0;
scanf("%d", &x);
for(int i = 0; i < n; i++)
{
if(a[i] <= x) continue;
else
{
int j = i;
while(j < n && a[j] > x) j++;
i = j - 1;
res ++;
}
}
printf("%d\n", res);
}
}
小阳买水果
链接:https://ac.nowcoder.com/acm/contest/12196/D
来源:牛客网
题目描述
水果店里有 nn个水果排成一列。店长要求顾客只能买一段连续的水果。
小阳对每个水果都有一个喜爱程度 a_ia
i
,最终的满意度为他买到的水果的喜欢程度之和。
如果和为正(不管是正多少,只要大于 00 即可),他就满意了。
小阳想知道在他满意的条件下最多能买多少个水果。
你能帮帮他吗?
输入描述:
第一行输入一个正整数 n,表示水果总数。
第二行输入 n 个整数 a_ia
i
,表示小阳对每个水果的喜爱程度。
输出描述:
一行一个整数表示结果。(如果 1 个水果都买不了,请输出 0)
示例1
输入
复制
5
0 0 -7 -6 1
输出
复制
1
备注:
1 \leq n \leq 2 \times 10^6,|a_i| \leq 10^31≤n≤2×10
6
,∣a
i
∣≤10
3
小阳买水果
链接:https://ac.nowcoder.com/acm/contest/12196/D
来源:牛客网
题目描述
水果店里有 nn个水果排成一列。店长要求顾客只能买一段连续的水果。
小阳对每个水果都有一个喜爱程度 a_ia
i
,最终的满意度为他买到的水果的喜欢程度之和。
如果和为正(不管是正多少,只要大于 00 即可),他就满意了。
小阳想知道在他满意的条件下最多能买多少个水果。
你能帮帮他吗?
输入描述:
第一行输入一个正整数 n,表示水果总数。
第二行输入 n 个整数 a_ia
i
,表示小阳对每个水果的喜爱程度。
输出描述:
一行一个整数表示结果。(如果 1 个水果都买不了,请输出 0)
示例1
输入
复制
5
0 0 -7 -6 1
输出
复制
1
备注:
1 \leq n \leq 2 \times 10^6,|a_i| \leq 10^31≤n≤2×10
6
, ,∣a
i
∣≤10
3
有这样一个性质,如果一个序列的和是大于0的话,那么这个序列的首尾两个数的前缀和的差是大于0的,于是我们可以利用这个性质来求解,首先排序,然后维护的是前面位置的最小值,然后与当前位置取最小值即可。需要注意的有有可能前缀和本身就是大于0的,所以加一个和为0的前缀和,还要防止相等的情况,所以我们要按照位置从大到小排序
/* _
_ooOoo_
o8888888o
88" . "88
(| -_- |)
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||_ \
| | \\\ - /'| | |
| \_| `\`---'// |_/ |
\ .-\__ `-. -'__/-. /
___`. .' /--.--\ `. .'___
."" '< `.___\_<|>_/___.' _> \"".
| | : `- \`. ;`. _/; .'/ / .' ; |
\ \ `-. \_\_`. _.'_/_/ -' _.' /
===========`-.`___`-.__\ \___ /__.-'_.'_.-'================
Please give me AC.
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
//#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
//using namespace __gnu_cxx;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl "\n"
//#define x first
//#define y second
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
inline void print(INT x) {
if (x < 0) { putchar('-'); x = -x; }
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
const int N = 2e6 + 10;
const int M = 3 * N;
const int mod = 1e9 + 7;
const int PP = 131;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
int n;
int a[N];
struct Node{
int val;
int pos;
bool operator<(const Node &W)const{
if (val == W.val) return pos < W.pos;
return val < W.val;
}
}node[N];
int pos1[N];
signed main(){
gt(n);
int sum = 0;
for (int i = 1; i <= n; i ++){
gt(a[i]);
sum += a[i];
node[i] = {sum, i};
pos1[i] = sum;
}
n ++;
node[n] = {0, 0};
pos1[0] = 0;
sort(node + 1, node + 1 + n);
int last = 0x3f3f3f3f;
int ans = 0;
for (int i = 1; i <= n; i ++){
// cout << node[i].pos << "----" << node[i].val << endl;
last = min(last, node[i].pos);
// cout << last << "----" << node[i].pos << "----" << node[last].val << "----" << node[i].val << endl;
if (last < node[i].pos && node[i].val > pos1[last]) ans = max(ans, node[i].pos - last);
}
cout << ans << endl;
return 0;
}
小雨的矩阵
链接:https://ac.nowcoder.com/acm/contest/12196/E
来源:牛客网
题目描述
小雨有一个 n \times nn×n 的矩阵,起点在(1,1),终点在(n,n),只能向下或向右走,且每次只能走 1 步。矩阵上每个点都有一个点权 a_{i,j}a
i,j
。
求走到终点的路径有多少不同的点权和。
输入描述:
第一行,输入一个正整数 n 。
接下来 n+1 行,每行 n 个数,表示 a_{i,j}a
i,j
。
输出描述:
共一行,输出有多少不同的点权和。
示例1
输入
复制
2
1 5
2 4
输出
复制
2
说明
(1,1) \rightarrow (2,1) \rightarrow (2,2):和为 7 。
(1,1) \rightarrow (1,2) \rightarrow (2,2):和为 10 。(1,1)→(2,1)→(2,2):和为7。(1,1)→(1,2)→(2,2):和为10。
备注:
1 \leq n \leq 8,0 \leq a_{i,j} \leq 501≤n≤8,0≤a
i,j
≤50
爆搜即可
/* _
_ooOoo_
o8888888o
88" . "88
(| -_- |)
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||_ \
| | \\\ - /'| | |
| \_| `\`---'// |_/ |
\ .-\__ `-. -'__/-. /
___`. .' /--.--\ `. .'___
."" '< `.___\_<|>_/___.' _> \"".
| | : `- \`. ;`. _/; .'/ / .' ; |
\ \ `-. \_\_`. _.'_/_/ -' _.' /
===========`-.`___`-.__\ \___ /__.-'_.'_.-'================
Please give me AC.
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
//#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
//using namespace __gnu_cxx;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl "\n"
//#define x first
//#define y second
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
inline void print(INT x) {
if (x < 0) { putchar('-'); x = -x; }
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
const int N = 20;
const int M = 3 * N;
const int mod = 1e9 + 7;
const int PP = 131;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
int a[N][N];
int n;
set<int> ss;
void dfs(int x, int y, int res){
if (x == n && y == n){
ss.insert(res);
return ;
}
for (int i = 0; i < 2; i ++){
int xx = x + dx[i], yy = y + dy[i];
if (xx > n || yy > n) continue;
dfs(xx, yy, res + a[xx][yy]);
}
}
signed main(){
gt(n);
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= n; j ++){
gt(a[i][j]);
}
}
dfs(1, 1, a[1][1]);
cout << ss.size() << endl;
return 0;
}
小石的妹子
链接:https://ac.nowcoder.com/acm/contest/12196/F
来源:牛客网
题目描述
小石有 n 个妹子,每个妹子都有一个细心程度 a_ia
i
和一个热心程度 b_ib
i
,
小石想给她们一个重要程度 t_it
i
(重要程度为 1 表示最重要,重要程度越小表示越重要)。
如果一个妹子 i 的细心程度和热心程度都比妹子 j 大,那么妹子 i 的重要程度要大于妹子 j 的重要程度,即妹子 i 比妹子 j 重要。
流程如下:
每次从所有没有重要程度的妹子中,找到若干妹子。对于这些妹子的任意一个,需要保证没有其他妹子比她更重要。然后把她们的重要程度标为 1 。下一次再从剩下没有重要程度的妹子中找到若干妹子,依然符合上述条件,然后把她们的重要程度标为 2,……,重复直到所有妹子都有自己的重要程度。
由于妹子太多,小石忙不过来,请你帮帮他。
输入描述:
第一行输入一个正整数 n,表示妹子的数量。
接下来 n 行,每行两个正整数 a_i,b_ia
i
,b
i
,描述每个妹子的细心程度和热心程度。
保证所有的 a_ia
i
两两不等,所有的 b_ib
i
两两不等。
输出描述:
共 n 行,第 i 行输出一个正整数 t_it
i
表示第 i 个妹子的重要程度。
示例1
输入
复制
5
1 4
2 2
3 3
4 1
5 5
输出
复制
2
3
2
2
1
说明
第一轮取第 5 个妹子(5 5),因为没有其他妹子比她重要,标记为 1;
第二轮取编号为 1,3,4 的妹子,因为对于其中的任意一个妹子,都没有其他妹子比她们重要,标记为 2;
第三轮把编号为 2 的妹子标记为 3 。
备注:
1 \leq n \leq 10^5,1 \leq a_i,b_i \leq 10^91≤n≤10
5
,1≤a
i
,b
i
≤10
9
30分的做法用拓扑排序,因为两个人如果一个人比另外一个人既热心又细心的话,那么这个人一定比另外一个人靠前
/* _
_ooOoo_
o8888888o
88" . "88
(| -_- |)
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||_ \
| | \\\ - /'| | |
| \_| `\`---'// |_/ |
\ .-\__ `-. -'__/-. /
___`. .' /--.--\ `. .'___
."" '< `.___\_<|>_/___.' _> \"".
| | : `- \`. ;`. _/; .'/ / .' ; |
\ \ `-. \_\_`. _.'_/_/ -' _.' /
===========`-.`___`-.__\ \___ /__.-'_.'_.-'================
Please give me AC.
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
//#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
//using namespace __gnu_cxx;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl "\n"
//#define x first
//#define y second
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
inline void print(INT x) {
if (x < 0) { putchar('-'); x = -x; }
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
const int N = 1e5 + 10;
const int M = 1e8 + 10;
const int mod = 1e9 + 7;
const int PP = 131;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
int h[N], e[M], ne[M], idx;
int a[N], b[N];
int n;
int din[N];
int cnt = 1;
int ans[N];
set<int> ss1, ss2;
void add(int a, int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void topsort(){
queue<int> q;
for (int i = 1; i <= n; i ++){
if (!din[i]){
q.push(i);
ans[i] = cnt;
// ss1.insert(i);
}
}
cnt ++;
while(q.size()){
int t = q.front();
q.pop();
for (int i = h[t]; ~i; i = ne[i]){
int j = e[i];
din[j] --;
if (din[j] == 0){
q.push(j);
ans[j] = ans[t] + 1;
}
}
}
}
signed main(){
ios;
memset(h, -1, sizeof h);
cin >> n;
for (int i = 1; i <= n; i ++){
cin >> a[i] >> b[i];
}
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= n; j ++){
if (a[i] < a[j] && b[i] < b[j]){
add(j, i);
din[i] ++;
}
}
}
topsort();
for (int i = 1; i <= n; i ++){
cout << ans[i] << endl;
}
return 0;
}
小石的图形
链接:https://ac.nowcoder.com/acm/contest/12196/G
来源:牛客网
题目描述
小石想在一面墙旁边建造一段长度为 n 的篱笆来围出一块地(如图)。
求最大的地的面积。
输入描述:
共一行,输入一个整数 n 。
输出描述:
共一行,输出最大面积,保留 3 位小数。
示例1
输入
复制
1
输出
复制
0.159
备注:
0 \leq n \leq 10^30≤n≤10
3
注意的是n是半圆的周长
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second
//int dx[4] = {0, 1, 0, -1};
//int dy[4] = {1, 0, -1, 0};
//typedef __int128 INT;
typedef pair<double, int> PDI;
typedef unsigned long long ULL;
inline int read(int out = 0)
{
char c;
while((c=getchar()) < 48 || c > 57);
while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
return out;
}
const int N = 1e5 + 10;
const int M = 3e6 + 10;
const int mod = 2333;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
signed main(){
int n;
cin >> n;
double ans = ((double)n * n * 1.0) / PI / 2.0;
printf("%.3lf\n", ans);
return 0;
}
小阳的贝壳
链接:https://ac.nowcoder.com/acm/contest/12196/H
来源:牛客网
题目描述
小阳手中一共有 n 个贝壳,每个贝壳都有颜色,且初始第 i 个贝壳的颜色为 col_icol
i
。现在小阳有 3 种操作:
1 l r x:给 [l,r][l,r] 区间里所有贝壳的颜色值加上 xx 。
2 l r:询问 [l,r][l,r] 区间里所有相邻贝壳 颜色值的差(取绝对值) 的最大值(若 l = rl=r 输出 0)。
3 l r :询问 [l,r][l,r] 区间里所有贝壳颜色值的最大公约数。
输入描述:
第一行输入两个正整数 n,mn,m,分别表示贝壳个数和操作个数。
第二行输入 nn 个数 col_icol
i
,表示每个贝壳的初始颜色。
第三到第 m + 2m+2 行,每行第一个数为 optopt,表示操作编号。接下来的输入的变量与操作编号对应。
输出描述:
共 m 行,对于每个询问(操作 2 和操作 3)输出对应的结果。
示例1
输入
复制
5 6
2 2 3 3 3
1 2 3 3
2 2 4
3 3 5
1 1 4 2
3 2 3
2 3 5
输出
复制
3
3
1
3
备注:
1 \leq n,m \leq 10^5,1 \leq col_i,x \leq 10^3,1 \leq opt \leq 3,1 \leq l \leq r \leq n1≤n,m≤10
5
,1≤col
i
,x≤10
3
,1≤opt≤3,1≤l≤r≤n
颜色的差的最大数提醒我们可以用差分数组,维护这个差分数组的最大值就是差的最大值,所有贝壳的颜色加x也可以用差分数组来维护,需要注意的是r+1必须小于等于n,防止出现问题,维护那个最大公约数,一段区间的最大公约数可以用差分数组表示,为第一个数,后面都是差分数组即可
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct Segment_tree
{
int l, r;
int sum, gcd, maxd;
} tr[N * 4];
int n, m;
int a[N];
int b[N];
int Gcd(int a, int b){
return b ? Gcd(b, a % b) : a;
}
void pushup(Segment_tree &u, Segment_tree &l, Segment_tree &r)
{
u.sum = l.sum + r.sum;
u.gcd = Gcd(l.gcd, r.gcd);
u.maxd = max(abs(l.maxd), abs(r.maxd));
}
void pushup(int u)
{
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void build(int u, int l, int r)
{
if (l != r) tr[u] = {l, r};
else
{
tr[u] = {l, r, a[l], abs(a[l]), abs(a[l])};
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int d)
{
if (tr[u].l == l && tr[u].r == l)
{
a[l] += d;
tr[u].sum = a[l];
tr[u].gcd = abs(a[l]);
tr[u].maxd = abs(a[l]);
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify(u << 1, l, d);
else modify(u << 1 | 1, l, d);
pushup(u);
}
Segment_tree query(int u, int l, int r)
{
if (tr[u].l >= l && tr[u].r <= r) return tr[u];
int mid = tr[u].l + tr[u].r >> 1;
if (r <= mid) return query(u << 1, l, r);
if (l > mid) return query(u << 1 | 1, l, r);
Segment_tree total, l_tree, r_tree;
l_tree = query(u << 1, l, r);
r_tree = query(u << 1 | 1, l, r);
pushup(total, l_tree, r_tree);
return total;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++){
cin >> b[i];
a[i] = (b[i] - b[i - 1]);
}
build(1, 1, n);
while (m --)
{
int op, l, r;
cin >> op >> l >> r;
if (op == 1){
int x;
cin >> x;
modify(1, l, x);
if (r < n) modify(1, r + 1, -x);
}
else if (op == 2){
if (l == r) cout << "0" << endl;
else{
cout << query(1, l + 1, r).maxd << endl;
}
}
else if (op == 3){
if (l == r) cout << query(1, 1, l).sum << endl;
else cout << Gcd(query(1, 1, l).sum, query(1, l + 1, r).gcd) << endl;
}
}
}
石头剪刀布
链接:https://ac.nowcoder.com/acm/contest/12196/I
来源:牛客网
题目描述
小阳和小石玩石头剪刀布的游戏,他们在地上画了 n 个长度为 1 的格子。
小阳一开始在 1 号格子,如果小阳赢了,那么他就能往前走 1 格(若在 n 号格子,则不往前走)。如果输了,就倒退 1 格(若在 1 号格子,则不往后走),平局原地不动。
小阳已经知道了他石头剪刀布赢的概率是 aa,平的概率是 bb,显然输的概率是 1-a-b1−a−b。
求小阳走到 n 号格子期望进行多少局石头剪刀布。
答案对 10^9+710
9
+7 取模。
输入描述:
第一行输入三个正整数 n,a,b,表示格子个数,小阳石头剪刀布赢的概率和平的概率。(概率已对 10^9+710
9
+7 取模)
输出描述:
共一行,输出答案。
示例1
输入
复制
50 200000002 400000003
输出
复制
630223353
备注:
1 \leq n \leq 100, 1 < a,b < 10^9 + 71≤n≤100,1<a,b<10
9
+7
石头剪刀布
链接:https://ac.nowcoder.com/acm/contest/12196/I
来源:牛客网
题目描述
小阳和小石玩石头剪刀布的游戏,他们在地上画了 n 个长度为 1 的格子。
小阳一开始在 1 号格子,如果小阳赢了,那么他就能往前走 1 格(若在 n 号格子,则不往前走)。如果输了,就倒退 1 格(若在 1 号格子,则不往后走),平局原地不动。
小阳已经知道了他石头剪刀布赢的概率是 aa,平的概率是 bb,显然输的概率是 1-a-b1−a−b。
求小阳走到 n 号格子期望进行多少局石头剪刀布。
答案对 10^9+710
9
+7 取模。
输入描述:
第一行输入三个正整数 n,a,b,表示格子个数,小阳石头剪刀布赢的概率和平的概率。(概率已对 10^9+710
9
+7 取模)
输出描述:
共一行,输出答案。
示例1
输入
复制
50 200000002 400000003
输出
复制
630223353
备注:
1 \leq n \leq 100, 1 < a,b < 10^9 + 71≤n≤100,1<a,b<10
9
+7
每个未知数表示的是从当前这个位置走到n的期望步数,推理出方程后,用高斯消元即可
**x1 x2 … xn;
x1 = (a)x2 + (1 - a)x1 + 1;
x2 = (a)x3 + (b)x2 + (1 -a - b)x1 + 1;
x3
x4 = (a)x5 + bx4 + (1 - a - b)x3 + 1;
…
xn= 0;
**
/* _
_ooOoo_
o8888888o
88" . "88
(| -_- |)
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||_ \
| | \\\ - /'| | |
| \_| `\`---'// |_/ |
\ .-\__ `-. -'__/-. /
___`. .' /--.--\ `. .'___
."" '< `.___\_<|>_/___.' _> \"".
| | : `- \`. ;`. _/; .'/ / .' ; |
\ \ `-. \_\_`. _.'_/_/ -' _.' /
===========`-.`___`-.__\ \___ /__.-'_.'_.-'================
Please give me AC.
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
//#include <ext/rope>
//#include <bitsdc++.h>
using namespace std;
//using namespace __gnu_cxx;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl "\n"
//#define x first
//#define y second
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
inline void print(INT x) {
if (x < 0) { putchar('-'); x = -x; }
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
const int N = 110;
const int M = 3 * N;
const int mod = 1e9 + 7;
const int PP = 131;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
int n, A, B;
int a[N][N];
int qmi(int a, int b){
int res = 1;
while(b){
if (b & 1) res = res % mod * a % mod;
a = a % mod * a % mod;
b >>= 1;
}
return res;
}
int ni(int x){
return qmi(x, mod - 2);
}
int gauss()
{
int c, r;
for (c = 0, r = 0; c < n; c ++ )
{
int t = r;
for (int i = r; i < n; i ++ )
if (abs(a[i][c]) > abs(a[t][c]))
t = i;
if (abs(a[t][c]) <= 0) continue;
for (int i = c; i < n + 1; i ++ ) swap(a[t][i], a[r][i]);
for (int i = n; i >= c; i -- ) a[r][i] = a[r][i] * ni(a[r][c]) % mod;
for (int i = r + 1; i < n; i ++ )
if (abs(a[i][c]) > 0)
for (int j = n; j >= c; j -- )
a[i][j] = ((a[i][j] - a[r][j] * a[i][c]) % mod + mod) % mod;
r ++ ;
}
for (int i = n - 1; i >= 0; i -- )
for (int j = i + 1; j < n; j ++ )
a[i][n] = ((a[i][n] - a[j][n] * a[i][j]) % mod + mod) % mod;
return 0;
}
signed main(){
cin >> n >> A >> B;
a[0][0] = mod - A;
a[0][1] = A % mod;
a[0][n] = -1;
for (int i = 1; i < n - 1; i ++){
a[i][i - 1] = ((1 - A - B) % mod + mod) % mod;
a[i][i] = (B - 1 + mod) % mod;
a[i][i + 1] = A;
a[i][n] = -1;
}
a[n - 1][n - 1] = 1;
gauss();
cout << a[0][n] << endl;
return 0;
}
小雨坐地铁
链接:https://ac.nowcoder.com/acm/contest/12196/J
来源:牛客网
题目描述
小雨所在的城市一共有 mm 条地铁线,分别标号为 1 号线,2 号线,……,m 号线。整个城市一共有 nn 个车站,编号为 1 \sim n1∼n 。其中坐 i 号线需要花费 a_ia
i
的价格,每坐一站就需要多花费 b_ib
i
的价格。i 号线有 c_ic
i
个车站,而且这 c_ic
i
个车站都已知,如果某一站有多条地铁线经过,则可以在这一站换乘到另一条地铁线,并且能多次换乘。现在小雨想从第 ss 个车站坐地铁到第 tt 个车站,地铁等待时间忽略不计,求最少花费的价格,若不能到达输出 -1 。(地铁是双向的,所以 ss 可能大于 tt)
输入描述:
第一行输入四个正整数 n,m,s,tn,m,s,t,分别表示车站个数,地铁线数,起点站和终点站。
第二行到第 m + 1m+1 行,每行前三个数为 a_i,b_i,c_ia
i
,b
i
,c
i
,分别表示坐 i 号线的价格,i 号线每坐一站多花的价格,i 号线车站个数。接下来 c_ic
i
个数,表示 i 号线的每一个车站的编号,单调递增。
输出描述:
共一行,一个数表示最小花费,若不能到达输出 -1 。
示例1
输入
复制
5 2 1 4
2 2 3 1 3 5
2 1 4 2 3 4 5
输出
复制
7
说明
坐 1 号线:花费 2;
1 \rightarrow 31→3:花费 2;
换乘 2 号线:花费 2;
3 \rightarrow 43→4:花费 1;
所以最小总花费为 7 。
备注:
1 \leq n \leq 10^3, 1 \leq m \leq 500,1 \leq s,t \leq n1≤n≤10
3
,1≤m≤500,1≤s,t≤n
1 \leq a_i,b_i \leq 100,1 \leq c_i \leq n,\sum\limits_{i = 1}^m c_i \leq 10^51≤a
i
,b
i
≤100,1≤c
i
≤n,
i=1
∑
m
c
i
≤10
5
分层图,想像坐高铁的过程建立出图即可
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
//typedef __int128 INT;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(int out = 0)
{
char c;
while((c=getchar()) < 48 || c > 57);
while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
return out;
}
const int N = 1e5 + 100;
const int M = 1e6;
const int mod = 2333;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
int n, m, s, t;
int h[M], e[M], ne[M], w[M], idx;
int dist[M];
bool st[M];
void add(int a, int b, int c){
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}
void dijkstra(){
priority_queue<PII, vector<PII>, greater<PII>> heap;
memset(dist, 0x7f, sizeof dist);
//cout << dist[t] << endl;
//if (dist[t] == 0x7f7f7f7f) cout << "------" << endl;
dist[s] = 0;
// st[s] = true;
heap.push({0, s});
while(heap.size()){
auto t = heap.top();
heap.pop();
int ver = t.second, distance = t.first;
// cout << ver << " " << distance << "--------" << endl;
if (st[ver]) continue;
st[ver] = true;
for (int i = h[ver]; ~i; i = ne[i]){
int j = e[i];
if (distance + w[i] < dist[j]){
dist[j] = distance + w[i];
heap.push({dist[j], j});
}
}
}
}
signed main(){
scanf("%lld%lld%lld%lld", &n, &m, &s, &t);
int edx = n + 1;
memset(h, -1, sizeof h);
for (int i = 1; i <= m; i ++){
int w1, w2;
scanf("%lld%lld", &w1, &w2);
int cnt;
gt(cnt);
bool flag = false;
while(cnt --){
int x;
scanf("%lld", &x);
add(edx, x, w1), add(x, edx, 0);
// cout << edx << "----" << x << "----" << w1 << endl;
if (flag){
add(edx, edx - 1, w2);
add(edx - 1, edx, w2);
// cout << edx - 1 << "---" << edx << "----" << w2 << endl;
}
else flag = true;
edx ++;
}
}
dijkstra();
if (dist[t] == 9187201950435737471) cout << "-1" << endl;
else cout << dist[t] << endl;
return 0;
}