zoukankan      html  css  js  c++  java
  • NOIP前板子复习

    再不复习板子我就是 [ 数据删除 ]

    高精度

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int power = 4, base = 10000; //修改压位 
    char a[233333], b[233333];
    //初始化 
    struct HP
    {
        int len, p[2333];
        HP() { len = 0; memset(p, 0, sizeof(p)); }
        HP(char *s)
        {
            len = (strlen(s) + power - 1) / power;
            memset(p, 0, sizeof(p));
            for(int i = 0, t = 0, w; i < strlen(s); i++, w *= 10)
            {
                if(i % power == 0) t++, w = 1;
                p[t] += (s[i] - '0') * w;
            }
        }
        void rev() { reverse(p + 1, p + len + 1); }
        void add(int k) { if(len || k) p[++len] = k; }
        void print()
        {
            printf("%d", p[len]);
            for(int i = len - 1; i > 0; i--) printf("%0*d", power, p[i]);
            printf("
    ");
        }
    } p, q, ans;
    //重载运算符 
    bool operator < (const HP &a, const HP &b)
    {
        if(a.len < b.len) return true;
        if(a.len > b.len) return false;
        for(int i = a.len; i > 0; i--)
            if(a.p[i] != b.p[i]) return a.p[i] < b.p[i];
        return false;
    }
    HP operator + (const HP &a, const HP &b)
    {
        HP c = a;
        c.len = max(a.len, b.len);
        for(int i = 1; i <= c.len; i++)
        {
            c.p[i] += b.p[i];
            c.p[i + 1] += c.p[i] / base;
            c.p[i] %= base;
        }
        if(c.p[c.len + 1]) c.len++;
        return c;
    }
    HP operator - (const HP &a, const HP &b)
    {
        HP c = a;
        for(int i = 1; i <= c.len; i++)
        {
            c.p[i] -= b.p[i];
            if(c.p[i] < 0) c.p[i] += base, c.p[i + 1]--;
        }
        while(c.len && !c.p[c.len]) c.len--;
        return c;
    }
    HP operator * (const HP &a, const HP &b)
    {
        HP c;
        c.len = a.len + b.len - 1;
        for(int i = 1; i <= a.len; i++)
            for(int j = 1; j <= b.len; j++)
            {
                c.p[i + j - 1] += a.p[i] * b.p[j];
                c.p[i + j] += c.p[i + j - 1] / base;
                c.p[i + j - 1] %= base;
            }
        while(c.p[c.len + 1]) c.len++;
        return c;
    }
    HP operator / (const HP &a, const HP &b)
    {
        HP u, v;
        u.len = a.len;
        for(int i = a.len; i > 0; i--)
        {
            v.add(a.p[i]), v.rev();
            while(!(v < b)) v = v - b, u.p[i]++;
            v.rev();
        }
        while(u.len && !u.p[u.len]) u.len--;
        return u;
    }
    HP operator % (const HP &a, const HP &b) { return a - (a / b) * b; }
    //以下是洛谷P1932主函数
    int main()
    {
        scanf("%s", &a), scanf("%s", &b);
        reverse(a, a + strlen(a)), reverse(b, b + strlen(b));
        p = HP(a), q = HP(b);
        ans = p + q; ans.print();
        if(p < q) { printf("-"); ans = q - p; }
        else ans = p - q;
        ans.print();
        ans = p * q; ans.print(); 
        ans = p / q; ans.print();
        ans = p % q; ans.print();
        return 0;
    }
    

    二分查找

    //估计没有人写这么骚气的二分查找吧...
    int l = left_limit, r = right_limit;
    while(l + 1 < r)
    {
        int mid = (l + r) >> 1;
        if(check(mid)) l = mid; //or r = mid;
        else r = mid; //or l = mid;
    } 
    st 1:
    if(check(l)) ans = l;
    else ans = r;
    st 2:
    if(check(r)) ans = r;
    else ans = l;
    

    tarjan 缩点

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    const int N = 10006, M = 100006;
    struct edge
    {
        int nxt, to;
    } e[M];
    int n, m, ans = 0, cnt = 0, id = 0, top = 0, col = 0;
    int a[N], head[N], low[N], dfn[N], c[N], st[N], s[M], t[M];
    int val[N], f[N], du[N], vis[N];
    
    inline int read()
    {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - 48; c = getchar(); }
        return x * f;
    }
    
    void add(int x, int y)
    {
        e[++cnt] = (edge) { head[x], y };
        head[x] = cnt;
    }
    
    void dfs(int x) //板子部分
    {
        dfn[x] = low[x] = ++id;
        st[++top] = x;
        vis[x] = 1;
        for(int i = head[x]; i; i = e[i].nxt)
        {
            int v = e[i].to;
            if(!dfn[v]) { dfs(v); low[x] = min(low[x], low[v]); }
            else if(vis[v]) low[x] = min(low[x], dfn[v]);
        }
        if(dfn[x] == low[x])
        {
            col++;
            st[top + 1] = -1;
            while(st[top + 1] != x)
            {
                c[st[top]] = col;
                vis[st[top--]] = 0;
            }
        }
    }
    
    void top_sort()
    {
        int m = col;
        for(int i = 1; i <= col; i++) f[i] = val[i];
        queue <int> q;
        for(int i = 1; i <= col; i++) if(!du[i]) q.push(i);
        while(!q.empty())
        {
            int a = q.front();
            q.pop();
            for(int i = head[a]; i; i = e[i].nxt)
            {
                int v = e[i].to;
                du[v]--;
                f[v] = max(f[v], f[a] + val[v]);
                if(!du[v]) q.push(v);
            }
        }
        for(int i = 1; i <= col; i++) ans = max(ans, f[i]);
    }
    
    int main()
    {
        n = read(), m = read();
        for(int i = 1; i <= n; i++) a[i] = read();
        for(int i = 1; i <= m; i++)
        {
            s[i] = read(), t[i] = read();
            add(s[i], t[i]);
        }
        memset(dfn, 0, sizeof(dfn));
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i++) if(!dfn[i]) dfs(i);
        memset(head, 0, sizeof(head));
        memset(val, 0, sizeof(val));
        cnt = 0;
        for(int i = 1; i <= m; i++)
            if(c[s[i]] != c[t[i]])
            {
                add(c[s[i]], c[t[i]]);
                du[c[t[i]]]++;
            }
        for(int i = 1; i <= n; i++) val[c[i]] += a[i];
        top_sort();
        printf("%d", ans);
        return 0;
    }
    

    二分图最大匹配

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 1010;
    int n, m, E, ans = 0, e[N][N], girl[N], use[N];
    
    bool find(int x)
    {
        for(int j = 1; j <= m; j++)
            if(e[x][j] == 1 && use[j] == 0)
            {
                use[j] = 1;
                if(girl[j] == 0 || find(girl[j]))
                {
                    girl[j] = x;
                    return true;
                }
            }
        return false;
    }
    
    int main()
    {
        scanf("%d%d%d", &n, &m, &E);
        memset(e, 0, sizeof(e));
        memset(girl, 0, sizeof(girl));
        for(int u, v, i = 1; i <= E; i++)
        {
            scanf("%d%d", &u, &v);
            if(u < 1 || u > n || v < 1 || v > m) continue;
            e[u][v] = 1;
        }
        for(int i = 1; i <= n; i++)
        {
            memset(use, 0, sizeof(use));
            ans += find(i);
        }
        printf("%d", ans);
        return 0;
    }
    

    状压 dp 枚举子集

    for(int i = S; i; i = ((i - 1) & S))
    

    Kruskal 最小生成树

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    using namespace std;
    
    const int N = 2333333;
    LL n, m, ans = 0, f[N];
    struct edge { LL u, v, w; } e[N];
    bool cmp(edge a, edge b) { return a.w < b.w; }
    LL find(LL x) { return x == f[x] ? x : f[x] = find(f[x]); }
    
    int main()
    {
        scanf("%lld%lld", &n, &m);
        for(int i = 1; i <= n; i++) f[i] = i;
        for(int i = 1; i <= m; i++)
            scanf("%lld%lld%lld", &e[i].u, &e[i].v, &e[i].w);
        sort(e + 1, e + m + 1, cmp);
        for(int i = 1; i <= m; i++)
            if(find(e[i].u) != find(e[i].v))
            {
                f[find(e[i].u)] = find(e[i].v);
                ans += e[i].w;
            }
        printf("%lld", ans);
        return 0;
    } 
    

    倍增求 LCA

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 500010;
    struct edge { int nxt, to; } e[N << 1];
    int n, m, s, cnt = 0, u, v, f[N][23], deep[N], head[N];
    
    void dfs(int x, int fa)
    {
        deep[x] = deep[fa] + 1;
        f[x][0] = x, f[x][1] = fa;
        for(int i = 2; i <= 20; i++)
            f[x][i] = f[f[x][i - 1]][i - 1];
        for(int i = head[x]; i; i = e[i].nxt)
            if(e[i].to != fa) dfs(e[i].to, x);
    }
    int LCA(int x, int y)
    {
        if(deep[x] < deep[y]) swap(x, y);
        for(int i = 20; i >= 0; i--)
            if(deep[f[x][i]] >= deep[y]) x = f[x][i];
        if(x == y) return x;
        for(int i = 20; i >= 0; i--)
            if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
        return f[x][1];
    }
    void add(int x, int y) { e[++cnt] = (edge) { head[x], y }; head[x] = cnt; }
    
    int main()
    {
        scanf("%d%d%d", &n, &m, &s);
        memset(head, 0, sizeof(head));
        for(int i = 1; i < n; i++)
            scanf("%d%d", &u, &v), add(u, v), add(v, u);
        deep[0] = 0, dfs(s, 0);
        while(m--) scanf("%d%d", &u, &v), printf("%d
    ", LCA(u, v));
        return 0;
    }
    

    spfa

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define LL long long
    using namespace std;
    
    const int N = 2333333;
    struct edge { LL nxt, to, w; } e[N << 1];
    LL n, m, s, cnt = 0, head[N], dis[N], vis[N];
    
    void add(LL x, LL y, LL w)
    {
        e[++cnt] = (edge) { head[x], y, w };
        head[x] = cnt;
    }
    
    void spfa()
    {
        for(int i = 0; i <= n + 1; i++) dis[i] = (1 << 31) - 1;
        memset(vis, 0, sizeof(vis));
        queue <LL> q;
        q.push(s);
        vis[s] = 1, dis[s] = 0;
        while(!q.empty())
        {
            LL a = q.front();
            q.pop();
            vis[a] = 0;
            for(int i = head[a]; i; i = e[i].nxt)
            {
                LL v = e[i].to;
                if(dis[v] > dis[a] + e[i].w)
                {
                    dis[v] = dis[a] + e[i].w;
                    if(!vis[v]) { vis[v] = 1; q.push(v); }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%lld%lld%lld", &n, &m, &s);
        for(LL u, v, w, i = 1; i <= m; i++)
        {
            scanf("%lld%lld%lld", &u, &v, &w);
            add(u, v, w);
        }
        spfa();
        for(int i = 1; i <= n; i++) printf("%lld ", dis[i]);
        return 0;
    }
    

    dijkstra + 堆优化

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define LL long long
    using namespace std;
    
    const int N = 2333333;
    struct edge { LL nxt, to, w; } e[N];
    LL n, m, s, cnt = 0, vis[N], dis[N], head[N];
    
    void add(LL x, LL y, LL w)
    {
        e[++cnt] = (edge) { head[x], y, w };
        head[x] = cnt;
    }
    
    struct node
    {
        LL x, dis;
        friend bool operator < (node x, node y) { return x.dis > y.dis; }
    };
    
    void dijkstra()
    {
        priority_queue <node> q;
        memset(dis, 0x7f7f7f, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        dis[s] = 0, q.push((node) { s, 0 });
        while(!q.empty())
        {
            LL a = q.top().x;
            q.pop();
            if(vis[a]) continue;
            vis[a] = 1;
            for(int i = head[a]; i; i = e[i].nxt)
            {
                LL v = e[i].to;
                if(dis[v] > dis[a] + e[i].w)
                {
                    dis[v] = dis[a] + e[i].w;
                    if(!vis[v]) q.push((node) { v, dis[v] });
                }
            }
        }
    }
    
    int main()
    {
        scanf("%lld%lld%lld", &n, &m, &s);
        memset(head, 0, sizeof(head));
        for(LL u, v, w, i = 1; i <= m; i++)
            scanf("%lld%lld%lld", &u, &v, &w), add(u, v, w);
        dijkstra();
        for(int i = 1; i <= n; i++) printf("%lld ", dis[i]);
        return 0;
    }
    

    并查集

    用时 (mathrm{2 space min})

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 2333333;
    int n, m, f[N];
    int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) f[i] = i;
        for(int x, y, z, i = 1; i <= m; i++)
        {
            scanf("%d%d%d", &z, &x, &y);
            if(z == 1) f[find(x)] = find(y);
            else
            {
                if(find(x) == find(y)) printf("Y
    ");
                else printf("N
    ");
            }
        }
        return 0;
    }
    

    树状数组

    用时 (5 space mathrm{min})

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    #define lowbit(x) (x & (-x))
    using namespace std;
    
    const int N = 2333333;
    LL n, m, t[N];
    
    void add(LL x, LL k) { while(x <= n) t[x] += k, x += lowbit(x); }
    LL query(LL x)
    {
        LL res = 0;
        while(x) res += t[x], x -= lowbit(x);
        return res;
    }
    
    int main()
    {
        scanf("%lld%lld", &n, &m);
        for(LL a, i = 1; i <= n; i++) scanf("%d", &a), add(i, a);
        for(LL opt, x, y, i = 1; i <= m; i++)
        {
            scanf("%lld%lld%lld", &opt, &x, &y);
            if(opt == 1) add(x, y);
            else printf("%lld
    ", query(y) - query(x - 1));
        }
        return 0;
    }
    

    线段树 单点修改 + 区间查询

    用时 (7 space mathrm{min})

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define LL long long
    using namespace std;
    
    const LL N = 666666;
    LL n, m, a[N], sum[N << 2];
    
    struct Segment_Tree
    {
        void push_up(LL x) { sum[x] = sum[x << 1] + sum[x << 1 | 1]; }
        void build(LL x, LL l, LL r)
        {
            if(l == r)
            {
                sum[x] = a[l];
                return ;
            }
            LL mid = (l + r) >> 1;
            build(x << 1, l, mid);
            build(x << 1 | 1, mid + 1, r);
            push_up(x);
        }
        void update(LL x, LL l, LL r, LL std, LL k)
        {
            if(r < std || l > std) return ;
            if(l == std && r == std)
            {
                sum[x] += k;
                return ;
            }
            LL mid = (l + r) >> 1;
            update(x << 1, l, mid, std, k);
            update(x << 1 | 1, mid + 1, r, std, k);
            push_up(x);
        }
        LL query(LL x, LL l, LL r, LL stdl, LL stdr)
        {
            if(l > stdr || r < stdl) return 0;
            if(stdl <= l && stdr >= r) return sum[x];
            LL mid = (l + r) >> 1;
            return query(x << 1, l, mid, stdl, stdr) + 
            query(x << 1 | 1, mid + 1, r, stdl, stdr);
            push_up(x);
        }
    } tree;
    
    int main()
    {
        scanf("%lld%lld", &n, &m);
        for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        tree.build(1, 1, n);
        for(LL opt, x, y, i = 1; i <= m; i++)
        {
            scanf("%lld%lld%lld", &opt, &x, &y);
            if(opt == 1) tree.update(1, 1, n, x, y);
            else printf("%lld
    ", tree.query(1, 1, n, x, y));
        }
        return 0;
    }
    

    线段树 区间修改 + 单点查询

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 2333333;
    int n, m, a[N], tag[N], sum[N];
    
    struct Segment_Tree
    {
        void push_up(int x) { sum[x] = sum[x << 1] + sum[x << 1 | 1]; }
        void push_down(int x, int l, int r)
        {
            int mid = (l + r) >> 1;
            tag[x << 1] += tag[x];
            tag[x << 1 | 1] += tag[x];
            sum[x << 1] += tag[x] * (mid - l + 1);
            sum[x << 1 | 1] += tag[x] * (r - mid);
            tag[x] = 0;
        }
        void build(int x, int l, int r)
        {
            if(l == r)
            {
                sum[x] = a[l];
                return ;
            } 
            int mid = (l + r) >> 1;
            build(x << 1, l, mid);
            build(x << 1 | 1, mid + 1, r);
            push_up(x);
        }
        void update(int x, int l, int r, int stdl, int stdr, int k)
        {
            if(l > stdr || r < stdl) return ;
            if(stdl <= l && stdr >= r)
            {
                tag[x] += k, sum[x] += k * (r - l + 1);
                push_down(x, l, r);
                return ;
            }
            int mid = (l + r) >> 1;
            push_down(x, l, r);
            update(x << 1, l, mid, stdl, stdr, k);
            update(x << 1 | 1, mid + 1, r, stdl, stdr, k);
            push_up(x);
        }
        int query(int x, int l, int r, int std)
        {
            if(l > std || r < std) return 0;
            if(l == std && r == std) return sum[x];
            int mid = (l + r) >> 1;
            push_down(x, l, r);
            return query(x << 1, l, mid, std) + 
            query(x << 1 | 1, mid + 1, r, std);
            push_up(x);
        }
    } tree;
    
    int main()
    {
        scanf("%d%d", &n, &m);
        memset(tag, 0, sizeof(tag));
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        tree.build(1, 1, n);
        for(int opt, x, y, k, i = 1; i <= m; i++)
        {
            scanf("%d", &opt);
            if(opt == 1)
            {
                scanf("%d%d%d", &x, &y, &k);
                tree.update(1, 1, n, x, y, k);
            }
            else
            {
                scanf("%d", &x);
                printf("%d
    ", tree.query(1, 1, n, x));
            }
        }
        return 0;
    }
    

    线段树 区间修改 + 区间查询

    用时 (9 space mathrm{min})

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    using namespace std;
    
    const LL N = 100100;
    LL n, m, a[N], sum[N << 2], tag[N << 2];
    struct Segment_Tree
    {
        void push_up(LL x) { sum[x] = sum[x << 1] + sum[x << 1 | 1]; }
        void push_down(LL x, LL l, LL r)
        {
            LL mid = (l + r) >> 1;
            if(!tag[x]) return ;
            tag[x << 1] += tag[x], tag[x << 1 | 1] += tag[x];
            sum[x << 1] += (mid - l + 1) * tag[x];
            sum[x << 1 | 1] += (r - mid) * tag[x];
            tag[x] = 0;
        }
        void build(LL x, LL l, LL r)
        {
            if(l == r)
            {
                sum[x] = a[l];
                return ;
            }
            LL mid = (l + r) >> 1;
            build(x << 1, l, mid);
            build(x << 1 | 1, mid + 1, r);
            push_down(x, l, r), push_up(x);
        }
        void update(LL x, LL l, LL r, LL stdl, LL stdr, LL k)
        {
            if(l > stdr || r < stdl) return ;
            if(stdl <= l && stdr >= r)
            {
                tag[x] += k;
                sum[x] += (r - l + 1) * k;
                push_down(x, l, r);
                return ;
            }
            LL mid = (l + r) >> 1;
            push_down(x, l, r);
            update(x << 1, l, mid, stdl, stdr, k);
            update(x << 1 | 1, mid + 1, r, stdl, stdr, k);
            push_down(x, l, r), push_up(x);
        }
        LL query(LL x, LL l, LL r, LL stdl, LL stdr)
        {
            if(l > stdr || r < stdl) return 0;
            if(stdl <= l && stdr >= r) return sum[x];
            LL mid = (l + r) >> 1;
            push_down(x, l, r);
            return query(x << 1, l, mid, stdl, stdr) + 
            query(x << 1 | 1, mid + 1, r, stdl, stdr);
            push_up(x);
        }
    } tree;
    
    int main()
    {
        scanf("%lld%lld", &n, &m);
        for(LL i = 1; i <= n; i++) scanf("%lld", &a[i]);
        tree.build(1, 1, n);
        for(LL opt, x, y, k, i = 1; i <= m; i++)
        {
            scanf("%lld", &opt);
            if(opt == 1)
            {
                scanf("%lld%lld%lld", &x, &y, &k);
                tree.update(1, 1, n, x, y, k);
            }
            else
            {
                scanf("%lld%lld", &x, &y);
                printf("%lld
    ", tree.query(1, 1, n, x, y));
            }
        }
        return 0;
    }
    

    线段树 区间乘法 + 区间加法

    用时 (114514 space mathrm{min})

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define LL long long
    using namespace std;
    
    const int N = 2333333;
    LL n, m, p, a[N], sum[N], mul[N], add[N];
    
    struct Segment_Tree
    {
        void push_up(LL x) { sum[x] = (sum[x << 1] + sum[x << 1 | 1] + p) % p; }
        void push_down(LL x, LL l, LL r)
        {
            LL mid = (l + r) >> 1;
            mul[x << 1] = (mul[x << 1] * mul[x] + p) % p;
            mul[x << 1 | 1] = (mul[x << 1 | 1] * mul[x] + p) % p;
            add[x << 1] = (add[x << 1] * mul[x] + add[x] + p) % p;
            add[x << 1 | 1] = (add[x << 1 | 1] * mul[x] + add[x] + p) % p;
            sum[x << 1] = (sum[x << 1] * mul[x] + add[x] * (mid - l + 1) + p) % p;
            sum[x << 1 | 1] = (sum[x << 1 | 1] * mul[x] + add[x] * (r - mid) + p) % p;
            mul[x] = 1, add[x] = 0;
        } 
        void build(LL x, LL l, LL r)
        {
            add[x] = 0, mul[x] = 1;
            if(l == r)
            {
                sum[x] = (a[l] + p) % p;
                return ;
            }
            LL mid = (l + r) >> 1;
            build(x << 1, l, mid);
            build(x << 1 | 1, mid + 1, r);
            push_up(x);
        }
        void update1(LL x, LL l, LL r, LL stdl, LL stdr, LL k)
        {
            if(l > stdr || r < stdl) return ;
            if(stdl <= l && stdr >= r)
            {
                mul[x] = (mul[x] * k + p) % p;
                add[x] = (add[x] * k + p) % p;
                sum[x] = (sum[x] * k + p) % p;
                push_down(x, l, r);
                return ;
            }
            LL mid = (l + r) >> 1;
            push_down(x, l, r);
            update1(x << 1, l, mid, stdl, stdr, k);
            update1(x << 1 | 1, mid + 1, r, stdl, stdr, k);
            push_down(x, l, r), push_up(x);
        }
        void update2(LL x, LL l, LL r, LL stdl, LL stdr, LL k)
        {
            if(l > stdr || r < stdl) return ;
            if(stdl <= l && stdr >= r)
            {
                add[x] = (add[x] + k + p) % p;
                sum[x] = (sum[x] + k * (r - l + 1) + p) % p;
                push_down(x, l, r);
                return ;
            }
            LL mid = (l + r) >> 1;
            push_down(x, l, r);
            update2(x << 1, l, mid, stdl, stdr, k);
            update2(x << 1 | 1, mid + 1, r, stdl, stdr, k);
            push_down(x, l, r), push_up(x);
        }
        LL query(LL x, LL l, LL r, LL stdl, LL stdr)
        {
            if(l > stdr || r < stdl) return 0;
            if(stdl <= l && stdr >= r) return (sum[x] + p) % p;
            LL mid = (l + r) >> 1;
            push_down(x, l, r);
            return (query(x << 1, l, mid, stdl, stdr) + 
            query(x << 1 | 1, mid + 1, r, stdl, stdr) + p) % p;
        }
    } tree;
    
    int main()
    {
        scanf("%lld%lld%lld", &n, &m, &p);
        for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        tree.build(1, 1, n);
        for(LL opt, x, y, k, i = 1; i <= m; i++)
        {
            scanf("%lld", &opt);
            if(opt == 1)
            {
                scanf("%lld%lld%lld", &x, &y, &k);
                tree.update1(1, 1, n, x, y, k);
            }
            else if(opt == 2)
            {
                scanf("%lld%lld%lld", &x, &y, &k);
                tree.update2(1, 1, n, x, y, k);
            }
            else
            {
                scanf("%lld%lld", &x, &y);
                printf("%lld
    ", tree.query(1, 1, n, x, y));
            }
        }
        return 0;
    }
    

    快速幂

    int poww(int b, int p, int k)
    {
        int ans = 1;
        while(p)
        {
            if(p & 1) ans = (ans * b) % k;
            b = (b * b) % k;
            p >>= 1;
        }
        return ans;
    }
    

    单调队列

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 2333333;
    long long n, k, head = 1, tail = 0, a[N], q[N];
    
    int main()
    {
        scanf("%lld%lld", &n, &k);
        memset(q, 0, sizeof(q));
        for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        for(int i = 1; i <= n; i++)
        {
            while(head <= tail && q[head] <= i - k) head++;
            while(head <= tail && a[q[tail]] >= a[i]) tail--;
            q[++tail] = i;
            if(i >= k) printf("%lld ", a[q[head]]);
        }
        printf("
    ");
        head = 1, tail = 0, memset(q, 0, sizeof(q));
        for(int i = 1; i <= n; i++)
        {
            while(head <= tail && q[head] <= i - k) head++;
            while(head <= tail && a[q[tail]] <= a[i]) tail--;
            q[++tail] = i;
            if(i >= k) printf("%lld ", a[q[head]]);
        }
        return 0;
    }
    

    01 背包

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 23333;
    int t, n, w[N], v[N], f[N];
    
    int main()
    {
        scanf("%d%d", &t, &n);
        memset(f, 0, sizeof(f));
        for(int i = 1; i <= n; i++) scanf("%d%d", &w[i], &v[i]);
        for(int i = 1; i <= n; i++)
            for(int j = t; j >= w[i]; j--)
                f[j] = max(f[j], f[j - w[i]] + v[i]);
        printf("%d", f[t]);
        return 0;
    }
    
  • 相关阅读:
    带轮播图、导航栏、商品的简单html,以及轮播图下边数字随轮播图的改变而改变
    设计table表格,用js设计偶数行和奇数行显示不同的颜色
    用js实现九九乘法口诀两种方式
    [FW]修复ubutnu12.04+win7的grub2引导
    How to compile Linux kernel in fedora 6
    [Fw]初探linux中断系统(2)
    [Fw]初探linux中断系统(1)
    Regular Expression 範例
    [fw]IDT表的初始化
    [Fw]中断的初始化
  • 原文地址:https://www.cnblogs.com/Andy-park/p/14077498.html
Copyright © 2011-2022 走看看