乱七八糟的笔记(没有原理……)

前言

因为loceaner太菜了,他什么东西都不会
所以他打算学一个东西就记录一下
不过因为他很菜,所以他不会写原理……
而且,他希望在2019CSP之前不会断更
就酱紫,就是写给他自己的……因为他太菜了

基础算法

二维前缀和

//知识点:二维前缀和
/*
By:Loceaner
*/
#include 
#include 
#include 
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

const int N = 1000;

int n, m;
int a[N][N], b[N][N];

int main() {
    n = read(), m = read();
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            a[i][j] = read();
            b[i][j] = a[i][j] + b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
        }
    }
    for(int i, u1, v1, u2, v2; i <= m; i++) {
        u1 = read(), v1 = read(), u2 = read(), v2 = read();
        cout << b[u2][v2] - b[u1 - 1][v2] - b[u2][v1 - 1] + b[u1 - 1][v1 - 1] << '\n';
    } 
    return 0;
}

二维差分

//知识点:
/*
By:Loceaner
*/
#include 
#include 
#include 
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

const int N = 1e3 + 11;

int n, m, a[N][N];

int main() {
    n = read(), m = read();
    for(int i = 1, u1, u2, v1, v2; i <= m; i++) {
        u1 = read(), v1 = read(), u2 = read(), v2 = read();
        a[u1][v1] += 1;
        a[u2 + 1][v2 + 1] += 1;
        a[u2 + 1][v1] -= 1;
        a[u1][v2 + 1] -= 1;
    }
    //C[x1][y1] += x ,  C[x2 + 1][y2 + 1] += x ,  C[x1][y2 + 1] -= x , C[x2 + 1][y1] -= x;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];;
        } 
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            cout << a[i][j] << ' ';
        }
        cout << '\n';
    }
    return 0;
}

排序不等式

给定3组数\(a, b, c\)
\(a[1]\)~\(a[n]\),\(b[1]\)~\(b[n]\),\(c[1]\)~\(c[n]\)
其中\(c[1]\)~\(c[n]\)\(b[1]\)~\(b[n]\)的乱序排列
\(a[1]*b[n]+a[2]*b[n-1]+...<=a[1]*c[1]+a[2]*c[2]+...<=a[1]*b[1]+a[2]*b[2]+...\)
即:逆序和 <= 乱序和 <= 正序和

关于\(long\ long\)

在日常的题目中,一定要看好数据范围,如果会爆\(int\)的话,不要忘记开\(long long\)(无数次被坑!!)

高精度模板

最让人烦的就是高精度了,某些题并不难,但是要写高精。。烦\(\color{white}{(ps:板子来自lfd)}\)

namespace BigInteger {
    struct Big_integer {
        int d[10005], len;
        void clean() {while(len > 1 and !d[len - 1]) len--;}
        Big_integer() {memset(d, 0, sizeof d);len = 1;}
        Big_integer(int num) {*this = num;}
        Big_integer operator = (const char* num) {
            memset(d, 0, sizeof d);
            len = strlen(num);
            for (int i = 0; i < len; i++) d[i] = num[len - 1 - i] - '0';
            clean();
            return *this;
        }
        Big_integer operator = (int num) {
            char s[10005];
            sprintf(s, "%d", num);
            *this = s;
            return *this;
        }
        Big_integer operator * (const Big_integer &b) const {
            int i, j;
            Big_integer c;
            c.len = len + b.len;
            for (j = 0; j < b.len; j++)
                for (i = 0; i < len; i++)
                    c.d[i + j] += d[i] * b.d[j];
            for (i = 0; i < c.len - 1; i++) c.d[i + 1] += c.d[i] / 10, c.d[i] %= 10;
            c.clean();
            return c;
        }
        Big_integer operator / (const int &b) {
            int i, j, a = 0;
            Big_integer c = *this;
            for (i = len - 1; i >= 0; i--) {
                a = a * 10 + d[i];
                for (j = 0; j < 10; j++) if (a < b * (j + 1)) break;
                c.d[i] = j;
                a = a - b * j;
            }
            c.clean();
            return c;
        }
        bool operator < (const Big_integer &b) const {
            if (len != b.len) return len < b.len;
            for (int i = len - 1; i >= 0; i--)
                if (d[i] != b.d[i])
                    return d[i] < b.d[i];
            return false;
        }
        string str() const {
            char s[10005];
            for (int i = 0; i < len; i++) s[len - 1 - i] = d[i] + '0';
            return s;
        }
    };
    istream& operator >> (istream& in, Big_integer &x) {
        string s;
        in >> s;
        x = s.c_str();
        return in;
    }
    ostream& operator << (ostream& out, const Big_integer &x) {
        out << x.str();
        return out;
    }
}
using namespace BigInteger;

数据结构

单调栈

for(int i = 0; i < T.size(); i++){
  while(! stk.empty() && stk.top() > T[i]){
    ​stk.pop();
  }
  stk.push(A[i]);
}

单调队列

上经典的滑动窗口问题

#include 
#include 
#include 
#include 
#define maxn 1000100
using namespace std;
int q[maxn], a[maxn];
int n, k;
void getmin() {
    int head = 0, tail = 0;
    for (int i = 1; i < k; i++) {
        while (head <= tail && a[q[tail]] >= a[i]) tail--;
        q[++tail] = i;
    }
    for (int i = k; i <= n; i++) {
        while (head <= tail && a[q[tail]] >= a[i]) tail--;
        q[++tail] = i;
        while (q[head] <= i - k) head++;
        printf("%d ", a[q[head]]);
    }
}

void getmax() {
    int head = 0, tail = 0;
    for (int i = 1; i < k; i++) {
        while (head <= tail && a[q[tail]] <= a[i]) tail--;
        q[++tail] = i;
    }
    for (int i = k; i <= n; i++) {
        while (head <= tail && a[q[tail]] <= a[i]) tail--;
        q[++tail] = i;
        while (q[head] <= i - k) head++;
        printf("%d ", a[q[head]]);
    }
}

int main() {
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    getmin();
    printf("\n");
    getmax();
    printf("\n");
    return 0;
}

数学/数论

快速乘

//知识点:快速乘
/*
By:Loceaner
*/
#include 
#include 
#include 
#define int long long
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

int a, b, p, ans;

int mul(int a, int b, int mod) {
    int res = 0;
    while(b) {
        if(b & 1) res = (res + a) % mod;
        a = (a + a) % mod;
        b >>= 1;
    }
    return res % mod;
}

signed main() {
    a = read(), b = read(), p = read();
    ans = mul(a, b, p);
    cout << ans << '\n';
    return 0;
}

快速幂

//知识点:快速幂 
/*
By:Loceaner
*/
#include 
#include 
#include 
#define int long long
using namespace std;

inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    return x * f;
}

int a, b, p, ans;

int power(int a, int b, int mod) {
    int res = 1;
    while(b) {
        if(b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res % mod;
}

signed main() {
    a = read(), b = read(), p = read();
    ans = power(a, b, p);
    cout << ans << '\n';
    return 0;
}

埃氏筛

void prime(int n) {
    cnt = 0;
    vis[0] = vis[1] = 1;
    for(int i = 2; i <= n; ++i) {
        if(!vis[i]) {
            p[++cnt] = i;
            for(int j = i * i; j <= n; j+=i) {
                vis[j] = true;
            }
        }
    }
}

线性筛

int vis[N], p[N], cnt;

void prepare() {
    vis[0] = vis[1] = 1;
    for(int i = 2; i <= n; i++) {
        if(!vis[i]) p[++cnt] = i;
        for(int j = 1; j <= cnt; j++) {
            if(i * p[j] > n) break;
            vis[i * p[j]] = 1;
            if(i % p[j] == 0) break;
        }
    }
}

你可能感兴趣的:(乱七八糟的笔记(没有原理……))