voidquick_sort(int q[], int l, int r) { if(l >= r) return; //int x = [q(l + r +1) / 2], i = l - 1, j = r + 1; int x = q[l + r >> 1], i = l - 1, j = r + 1; // 注意是向上取整,因为向下取整可能使得x取到q[l] while(i < j) { do i ++ ; while (q[i] < x); // 不能取等号,因为若数据都相等则无限循环触发数组越界 do j -- ; while (q[j] > x); // do while 保证i,j一定更新 if (i < j) swap(q[i], q[j]); //可以使用if(i <= j) swap(q[i], q[j]); } quick_sort(q, l, j), quick_sort(q, j + 1, r); //quick_sort(q, l, i - 1), quick_sort(q, i, r); } //关于quick_sort()取i,j的问题,若为i则取右边界,若为j则取左边界
intmain() { scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
quick_sort(q, 0, n-1);
for (int i = 0; i < n; i ++ ) printf("%d ", q[i]);
int k = 0, i = l, j = mid + 1; while(i <= mid && j <= r) if (q[i] <= q[j]) tmp[ k ++ ] = q[ i ++ ]; //比较两部分 else tmp[ k ++ ] = q [ j ++ ]; while (i <= mid) tmp[ k ++ ] = q[ i ++ ]; //将剩余值写入, while (j <= r) tmp[ k ++ ] = q[ j ++ ]; · //由于前面的循环语句,这里最多只有一个while进行多次循环 for (i = l, j = 0; i <= r; i ++, j ++) q[i] = tmp[j]; //写回数组 } intmain() { scanf("%d", &n); for (int i = 0; i < n; i ++) scanf("%d", &q[i]); merge_sort(q, 0 , n-1); for (int i = 0; i < n; i++) printf("%d ", q[i]);
return0;
}
二分
整数二分
mid = (l+r+1)/2 找最后一个小于等于目标值的元素。(右边界)
true [mid, r ] l = mid
false [l, mid - 1] r = mid -1
mid = (1+r)/2 查找第一个大于等于目标值的元素。(左边界)
true [l, mid] r = mid
false [mid+1, r] l = mid +1
二分答案模板
1 2 3 4 5 6 7 8 9
while (left <= right) { int mid = left + (right - left) / 2; // 计算中间值 if (check(mid)) { // 检查 mid 是否满足条件 ans = mid; // 更新答案 right = mid - 1; // 尝试更小的值 } else { left = mid + 1; // 尝试更大的值 } }
1 2 3 4
//内置二分函数 int x = lower_bound(a, a + 8, 4) - a; //[a,a+8) 查找的值 >= 严格递增序列的插入位置 int y = upper_bound(a, a + 8, 4) - a; // > 非严格递增序列的插入位置 binary_search(start, end ,target): //若目标值存在则返回true,否则返回false
intmain() { scanf("%d %d", &n, &m); for (int i = 0; i < n; i ++) scanf("%d", & q[i]); while( m -- ) { int x; scanf("%d", &x);
int l = 0, r = n - 1; while (l < r) { int mid = l + r >> 1; //左半二分,确定左边界 if(q[mid] >= x) r = mid; else l = mid + 1; } if( q[l] != x) cout << "-1 -1" << endl; else { cout << l << ' '; int l = 0, r = n - 1; while (l < r) { int mid = l + r +1 >> 1; //右半二分,确定右边界 if(q[mid] <= x) l = mid; else r = mid - 1; } cout << l << endl; } } return0; }
浮点数二分
浮点数二分条件:区间长度大于精度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include<iostream> using namespace std;
intmain() { double x; cin >> x; double l = -10000, r = 10000; //l和r表示n的范围 while (r - l > 1e-8) //一般精度比题目+2次方 { double mid = (l + r) / 2; //二分 if( mid * mid * mid >= x) r = mid; else l = mid; } printf("%lf\n",l); return0; }
#include<iostream> #include<utility> #include<algorithm> usingnamespace std; typedeflonglong LL; constint N = 1e6+10; int arr[N];
typedef pair<int, int> PA; typedef pair<PA, int> PA2; int n,m;
intmain(){ cin >> n >> m; int x; for(int i = 0; i < n; i++) { cin >> arr[i]; } for(int i = 0; i < m; i++) { cin >> x; int pos = lower_bound(arr,arr+n,x) - arr;
vector<int> add(vector<int> &A, vector<int> &B) { vector<int> C; int t = 0; if (A.size() < B.size()) return add(B, A); for (int i = 0; i < A.size() || i < B.size(); i ++ ) { //t + = A[i]; if (i < A.size()) t += A[i]; if (i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10; //去进位 } if (t) C.push_back(1); //有无进位判断 return C;
}
intmain() { string a,b; vector<int> A, B; cin >> a >> b ; for (int i = a.size() - 1; i >= 0; i --) A.push_back(a[i] - '0'); //push_back在数组的最后添加一个数据,类似于栈 for (int i = b.size() - 1; i >= 0; i --) B.push_back(b[i] - '0');
auto C = add(A, B);
for (int i = C.size() - 1; i >= 0; i -- ) printf("%d", C[i]); return0;
boolcmp(vector<int> &A, vector<int> &B) { if(A.size() != B.size()) return A.size() > B.size(); for (int i = A.size() - 1; i >= 0; i -- ) if (A[i] != B[i]) return A[i] > B[i];
returntrue; }
vector<int> sub(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = 0 ,t = 0; i < A.size(); i++) { t = A[i] - t; //消除进位 if( i < B.size()) t -= B[i]; //运算 C.push_back((t + 10) % 10); //求绝对值 if ( t < 0) t = 1; //产生进位 else t = 0; }
while (C.size() > 1 && C.back() == 0) C.pop_back(); //去除多余的0
return C;
}
intmain() { string a,b; vector<int> A, B; cin >> a >> b ; for (int i = a.size() - 1; i >= 0; i --) A.push_back(a[i] - '0'); //push_back在数组的最后添加一个数据,类似于栈 for (int i = b.size() - 1; i >= 0; i --) B.push_back(b[i] - '0');
if (cmp(A, B)) //大减小 { auto C = sub(A, B); for (int i = C.size() - 1; i >= 0; i -- ) printf("%d", C[i]); } else { auto C = sub(B, A); printf("-"); for (int i = C.size() - 1; i >= 0; i -- ) printf("%d", C[i]); } return0;
vector<int> mul(vector<int> &A, int b) { vector<int> C; int t = 0; for (int i = 0; i < A.size() || t; i ++ ) { if (i < A.size()) t += A[i] * b; C.push_back(t % 10); t /= 10; } while (C.size() > 1 && C.back() == 0) C.pop_back(); //去除0
return C; }
intmain() { string a; int b; cin >> a >> b; if (b == 0) {printf("0"); return0;} //0特解
vector<int> A;
for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
auto C = mul(A, b);
for (int i = C.size() - 1; i >= 0; i --) printf("%d",C[i]);
vector<int> div(vector<int> &A, int b, int &r) { vector<int> C; r = 0;
for (int i = A.size() - 1; i >= 0 ; i -- ) { r = r * 10 + A[i]; C.push_back(r/b); r %= b; } reverse(C.begin(), C.end()); while (C.size() > 1 && C.back() == 0) C.pop_back(); //去除0
return C; }
intmain() { string a; int b; cin >> a >> b;
vector<int> A;
for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0'); int r; auto C = div(A, b, r);
for (int i = C.size() - 1; i >= 0; i --) printf("%d",C[i]); cout << endl << r <<endl; return0; }
import sys import os sys.setrecursionlimit(100000) input = lambda: sys.stdin.readline().strip()
arr = []
n,m,q = map(int,input().split())
arr.append([0]*(m+10))
for _ inrange(n): arr.append([0] + list(map(int,input().split())))
brr = [[0]*(m+10) for _ inrange(n+10)]
for i inrange(1,n+1): for j inrange(1,m+1): brr[i][j] = arr[i][j] - arr[i][j-1] - arr[i-1][j] + arr[i-1][j-1]
for _ inrange(q): x1,y1,x2,y2,c = map(int,input().split()) # 对矩形区域(x1,y1)到(x2,y2)增加c的差分操作 brr[x1][y1] += c # 影响所有右下区域 brr[x2+1][y1] -= c # 取消右侧影响 brr[x1][y2+1] -= c # 取消下侧影响 brr[x2+1][y2+1] += c # 补回重复减去的区域 for i inrange(1,n+1): for j inrange(1,m+1): arr[i][j] = brr[i][j] + arr[i][j-1] + arr[i-1][j] - arr[i-1][j-1] for i inrange(1, n+1): print(' '.join(map(str, arr[i][1:m+1])))
intfind(int x)//二分查找 { int l = 0, r = alls.size() - 1; while(l < r) { int mid = l + r >> 1; if(alls[mid] >= x) r = mid; else l = mid + 1; } return r + 1; }
intmain() { cin >> n >> m; for (int i = 0;i < n; i ++) { int x, c; cin >> x >> c; add.push_back({x,c}); alls.push_back(x); }
for (int i = 0;i < m; i ++) { int l, r; cin >> l >> r; query.push_back({l, r}); //存储查找键值 alls.push_back(l); alls.push_back(r); }
intfind(int x)//二分查找 { int l = 0, r = alls.size() - 1; while(l < r) { int mid = l + r >> 1; if(alls[mid] >= x) r = mid; else l = mid + 1; } return r + 1; }
intmain() { cin >> n >> m; for (int i = 0;i < n; i ++) { int x, c; cin >> x >> c; add.push_back({x,c}); alls.push_back(x); }
for (int i = 0;i < m; i ++) { int l, r; cin >> l >> r; query.push_back({l, r}); alls.push_back(l); alls.push_back(r); }