diff --git "a/2-\346\225\260\346\215\256\347\273\223\346\236\204.md" "b/2-\346\225\260\346\215\256\347\273\223\346\236\204.md" index 45d9690..028384e 100644 --- "a/2-\346\225\260\346\215\256\347\273\223\346\236\204.md" +++ "b/2-\346\225\260\346\215\256\347\273\223\346\236\204.md" @@ -34,7 +34,62 @@ class BIT }; ``` - +```cpp +template +struct Fenwick{ + int n; + vector tr; + + Fenwick(int n) : n(n), tr(n + 1, 0){} + + int lowbit(int x){ + return x & -x; + } + + void modify(int x, T c){//单点添加 + for(int i = x; i <= n; i += lowbit(i)) tr[i] += c; + } + + void modify(int l, int r, T c){//区间添加 + modify(l, c); + if (r + 1 <= n) modify(r + 1, -c); + } + + T query(int x){ + T res = T(); + for(int i = x; i; i -= lowbit(i)) res += tr[i]; + return res; + } + + T query(int l, int r){ + return query(r) - query(l - 1); + } + + int find_first(T sum){//和出现的第一位置 + int ans = 0; T val = 0; + for(int i = __lg(n); i >= 0; i--){ + if ((ans | (1 << i)) <= n && val + tr[ans | (1 << i)] < sum){ + ans |= 1 << i; + val += tr[ans]; + } + } + return ans + 1; + } + + int find_last(T sum){ + int ans = 0; T val = 0; + for(int i = __lg(n); i >= 0; i--){ + if ((ans | (1 << i)) <= n && val + tr[ans | (1 << i)] <= sum){ + ans |= 1 << i; + val += tr[ans]; + } + } + return ans; + } + +}; +using BIT = Fenwick; +``` ## 并查集 @@ -290,3 +345,16 @@ int query(int l, int r, int cl = 1, int cr = n, int p = 1) } ``` +## 单调队列 +```cpp +int p[N]; +int head=1,tail=0; +for(int i=1;i<=n;i++){ + if(head<=tail&&p[head]==i-k){//当前0 区间长度大于k时扔掉头部 + head++; + } + while(head<=tail&&a[p[tail]]<=a[i]) tail--;//此时求最大值 + p[++tail]=i; + //则head记录区间内最值 +} +``` \ No newline at end of file diff --git "a/3-\345\212\250\346\200\201\350\247\204\345\210\222.md" "b/3-\345\212\250\346\200\201\350\247\204\345\210\222.md" index 8a1110c..251c797 100644 --- "a/3-\345\212\250\346\200\201\350\247\204\345\210\222.md" +++ "b/3-\345\212\250\346\200\201\350\247\204\345\210\222.md" @@ -84,6 +84,12 @@ for (int i = 2; i <= n; i++) } } ``` +枚举s的二进制真子集 +```cpp +for(int j=s;j;j=(j-1)&s){ + //... +} +``` ## 数位DP diff --git "a/4-\346\225\260\345\255\246.md" "b/4-\346\225\260\345\255\246.md" index ae74d39..60f9216 100644 --- "a/4-\346\225\260\345\255\246.md" +++ "b/4-\346\225\260\345\255\246.md" @@ -209,3 +209,89 @@ void matrix::tra(matrix a) { } ``` +## 高斯消元 +求解线性方程组 + +将各系数合为矩阵,再将其变为上三角矩阵 + +过程中通常要保证选择的主元绝对值最大以保证精度 + +n^3 + +```cpp +const int N=100; +const double eps=1e-10; +int n; +double a[N+1][N+1],b[N+1]; + +void gauss(){ + int l=1; + for(int i=1;i<=n;i++){//n列 + for(int j=l;j<=n;j++){//找下面所有行中这一列处绝对值最大的 + if(abs(a[j][i])>abs(a[l][i])){ + for(int k=i;k<=n;k++){ + swap(a[l][k],a[j][k]); + } + swap(b[l],b[j]); + } + } + if(abs(a[l][i])eps){ + double delta=a[j][i]/a[l][i]; + for(int k=i;k<=n;k++){ + a[j][k]-=a[l][k]*delta; + } + b[j]-=b[l]*delta; + } + } + ++l; + } + + for(int i=l;i<=n;i++){//假如有剩下的行且b值不为0则无解 + if(abs(b[i])>eps){ + cout<<"无解"<