CSP-S 常用模板合集

Kruskal

Kruskal

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 200010
#define ll long long
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct Road{
    int x, y, w;
}road[M];
int n, m, f[M], tot, sum;
inline bool cmp(Road a, Road b) {return a.w < b.w;}
inline int find(int x) {return x == f[x] ? x : f[x] = find(f[x]);}
inline void Kruskal() {
    for(int i = 1; i <= n; i++) f[i] = i;
    sort(road+1, road+m+1, cmp);
    for(int i = 1; i <= m; i++) {
        int a = find(road[i].x), b = find(road[i].y);
        if(a != b) {
            f[a] = b;
            sum += road[i].w;
            tot++;
        }
    }
    return;
}

int main() {
    n = read(), m = read();
    for(int i = 1; i <= m; i++) road[i].x = read(), road[i].y = read(), road[i].w = read();
    Kruskal();
    if(tot != n-1) printf("orz\n");
    else printf("%d\n", sum);
    return 0;
}

SPFA

SPFA

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
//Mystery_Sky
//
#define M 500010
#define ll long long
#define INF 0x7fffff
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct Edge{
    int next, to, w;
}edge[M];
int cnt, head[M];
int n, m, s;
int dis[M], vis[M];
inline void add_edge(int u, int v, int w) {edge[++cnt].to = v; edge[cnt].next = head[u]; edge[cnt].w = w; head[u] = cnt;}
queue <int> Q;
inline void SPFA()
{
    for(int i = 1; i <= n; i++) dis[i] = INF;
    dis[s] = 0;
    Q.push(s);
    vis[s] = 1;
    while(!Q.empty()) {
        int x = Q.front(); Q.pop();
        vis[x] = 0;
        for(int i = head[x]; i; i = edge[i].next) {
            int y = edge[i].to;
            if(dis[y] > dis[x] + edge[i].w) {
                dis[y] = dis[x] + edge[i].w;
                if(!vis[y]) Q.push(y);
            }
        }
    }
    return;
}

int main() {
    n = read(), m = read(), s = read();
    for(int i = 1; i <= m; i++) {
        int u = read(), v = read(), w = read();
        add_edge(u, v, w);
    }
    SPFA();
    for(int i = 1; i <= n; i++) printf("%d ", dis[i]);
    return 0;
}

SPFA(判负环)

负环

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 100100
#define ll long long
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct node{
    int to, next, w;
}edge[M];
int n, m;
int head[M], cnt, ind[M], dis[M], vis[M];
inline void add_edge(int u, int v, int w) {edge[++cnt].to = v; edge[cnt].next = head[u]; edge[cnt].w = w; head[u] = cnt;}
queue <int> Q;
inline bool SPFA()//负环
{
    dis[1] = 0;
    ind[1] = 1;
    vis[1] = 1;
    Q.push(1);
    while(!Q.empty()) {
        int u = Q.front();
        Q.pop(); vis[u] = 0;
        for(int i = head[u]; i; i = edge[i].next) {
            int v = edge[i].to;
            if(dis[v] > dis[u] + edge[i].w) {
                dis[v] = dis[u] + edge[i].w;
                if(++ind[v] > n) return false;
                if(!vis[v]) Q.push(v), vis[v] = 1;
            }
        }
    }
    return true;
}
inline void INIT() {
    memset(dis, INF, sizeof(dis));
    while(!Q.empty()) Q.pop();
    memset(ind, 0, sizeof(ind));
    memset(vis, 0, sizeof(vis));
    memset(head, 0, sizeof(head));
    cnt = 0;
}
int main() {
    int t = read();
    while(t--) {
        INIT();
        n = read(), m = read();
        for(int i = 1; i <= m; i++) {
            int u = read(), v = read(), w = read();
            add_edge(u, v, w);
            if(w >= 0) add_edge(v, u, w);
        }
        if(SPFA()) printf("N0\n");
        else printf("YE5\n");
    }
    return 0;
}

Dijkstra(堆优化)

dijkstra

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
//Mystery_Sky
//
#define M 500010
#define ll long long
#define INF 0x7fffff
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct Edge{
    int next, to, w;
}edge[M];
int cnt, head[M];
int n, m, s;
int dis[M], vis[M];
inline void add_edge(int u, int v, int w) {edge[++cnt].to = v; edge[cnt].next = head[u]; edge[cnt].w = w; head[u] = cnt;}
struct node{
    int dis;
    int pos;
    inline bool operator <(const node& x) const{
        return x.dis < dis;
    }
};
priority_queue <node> Q;
inline void dijkstra()
{
    for(int i = 1; i <= n; i++) dis[i] = INF;
    dis[s] = 0;
    Q.push((node){0, s});
    while(!Q.empty()) {
        node top = Q.top(); Q.pop();
        int x = top.pos;
        if(vis[x]) continue;
        vis[x] = 1;
        for(int i = head[x]; i; i = edge[i].next) {
            int y = edge[i].to;
            if(dis[y] > dis[x] + edge[i].w) {
                dis[y] = dis[x] + edge[i].w;
                if(!vis[y]) Q.push((node){dis[y], y});
            }
        }
    }
    return;
}

int main() {
    n = read(), m = read(), s = read();
    for(int i = 1; i <= m; i++) {
        int u = read(), v = read(), w = read();
        add_edge(u, v, w);
    }
    dijkstra();
    for(int i = 1; i <= n; i++) printf("%d ", dis[i]);
    return 0;
}

拓扑排序

topo

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 500010
#define ll long long
#define Mod 80112002
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct Edge{
    int next, to;
}edge[M];
int cnt, head[M];
int n, m, s, ans;
int ind[M], out[M], f[M];
inline void add_edge(int u, int v) {edge[++cnt].to = v; edge[cnt].next = head[u]; head[u] = cnt;}
queue <int> Q;
inline void topo() {
    for(int i = 1; i <= n; i++) if(!ind[i]) Q.push(i), f[i]++;
    while(!Q.empty()) {
        int x = Q.front(); Q.pop();
        for(int i = head[x]; i; i = edge[i].next) {
            int y = edge[i].to;
            f[y] = (f[y] + f[x]) % Mod;
            ind[y]--;
            if(!ind[y]) Q.push(y);
        }
    }
}

int main() {
    n = read(), m = read();
    for(int i = 1; i <= m; i++) {
        int u = read(), v = read();
        out[u]++, ind[v]++;
        add_edge(u, v);
    }
    topo();
    for(int i = 1; i <= n; i++) 
        if(!out[i]) ans = (ans + f[i]) % Mod;
    printf("%d\n", ans % Mod);
    return 0;
}

并查集

并查集

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 200010
#define ll long long
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n, m;
int f[M];
inline int find(int x) {return x == f[x] ? x : f[x] = find(f[x]);}
int main() {
    n = read(), m = read();
    for(int i = 1; i <= n; i++) f[i] = i;
    for(int i = 1; i <= m; i++) {
        int opt = read(), a = read(), b = read();
        if(opt == 1) {
            int x = find(a), y = find(b);
            if(x != y) f[x] = y;
        }
        else {
            int x = find(a), y = find(b);
            if(x != y) printf("N\n");
            else printf("Y\n");
        }
    }
    return 0;
}

tarjan

tarjan

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 200010
#define ll long long
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct Edge{
    int next, to, w;
}edge[M];
int n, m, sum, ans;
int scc[M], sumscc, dfn[M], low[M], bl[M], out[M], size[M];
int cnt, head[M], vis[M];
stack <int> S;
inline void add_edge(int u, int v) {edge[++cnt].to = v; edge[cnt].next = head[u]; head[u] = cnt;}
inline void tarjan(int u) 
{
    dfn[u] = low[u] = ++sum;
    S.push(u);
    vis[u] = 1;
    for(int i = head[u]; i; i = edge[i].next) {
        int v = edge[i].to;
        if(!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(vis[v]) low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u]) {
        int j, c = 0;
        sumscc++;
        do {
            j = S.top(); S.pop();
            vis[j] = 0;
            bl[j] = sumscc;
            c++;
        }while(j != u);
        size[sumscc] = c;
    }
    return;
}
int main() {
    n = read(), m = read();
    for(int i = 1; i <= m; i++) {
        int u = read(), v = read();
        add_edge(u, v);
    } 
    for(int i = 1; i <= n; i++) 
        if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= n; i++) {
        for(int j = head[i]; j; j = edge[j].next) {
            int y = edge[j].to;
            if(bl[i] != bl[y]) out[bl[i]]++;
        }
    }
    sum = 0;
    for(int i = 1; i <= sumscc; i++) 
        if(!out[i]) ans = size[i], sum++;
    printf("%d\n", sum == 1 ? ans : 0);
    return 0;
}

tarjan(缩点)

tarjan(缩点)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <queue>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 100010
#define ll long long
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct Edge{
    int to, next;
}edge[M*4];
Edge edge1[M*4];
int cnt, head[M];
int cnt1, head1[M];
int n, m, sumscc, sum, tot, ans;
int a[M], vis[M], scc[M], dfn[M], low[M], e[M], p[M], b[M], ind[M], bl[M];
stack <int> S;
inline void add_edge(int u, int v) {edge[++cnt].to = v; edge[cnt].next = head[u]; head[u] = cnt;}
inline void add_edge1(int u, int v) {edge1[++cnt1].to = v; edge1[cnt1].next = head1[u]; head1[u] = cnt1;}
inline void tarjan(int u)
{
    dfn[u] = low[u] = ++sum;
    S.push(u);
    vis[u] = 1;
    for(int i = head[u]; i; i = edge[i].next) {
        int v = edge[i].to;
        if(!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(vis[v]) low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u]) {
        int j;
        sumscc++;
        do {
            j = S.top(); S.pop();
            vis[j] = 0;
            bl[j] = sumscc;
            scc[sumscc] += a[j];
        }while(j != u);
    }
}
int f[M];
queue <int> Q;
inline void bfs(int s)
{
    Q.push(s);
    f[s] = b[s];
    while(!Q.empty()) {
        int x = Q.front(); Q.pop();
        ans = max(ans, f[x]);
        for(int i = head1[x]; i; i = edge1[i].next) {
            int y = edge1[i].to;
            f[y] = f[x] + b[y];
            Q.push(y);
        }
    }
    return;
}
int main() {
    n = read(), m = read();
    for(int i = 1; i <= n; i++) a[i] = read();
    for(int i = 1; i <= m; i++) {
        int u = read(), v = read();
        add_edge(u, v);
    }
    for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= n; i++) {
        if(bl[i] && e[bl[i]]) continue;
        if(bl[i]) {
            tot++;
            e[bl[i]] = tot;
            b[tot] = scc[bl[i]];
        }
        else {
           tot++;
           p[i] = tot;
           b[tot] = a[i];
        }
    }
    for(int i = 1; i <= n; i++) {
        int x;
        if(bl[i]) x = e[bl[i]];
        else x = p[i];
        for(int j = head[i]; j; j = edge[j].next) {
            int y = edge[j].to;
            if(bl[y] == bl[i] && bl[i]) continue;
            if(bl[y]) add_edge1(x, e[bl[y]]), ind[e[bl[y]]]++;
            else add_edge1(x, p[y]), ind[p[y]]++;
        }
    }
    for(int i = 1; i <= tot; i++) if(!ind[i]) bfs(i);
    printf("%d\n", ans);
    return 0;
}

KMP

KMP

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 2000100
#define ll long long
int nxt[M];
char s1[M], s2[M];
int main() {
    scanf("%s", s1+1);
    scanf("%s", s2+1);
    int n = strlen(s1+1), m = strlen(s2+1);
    nxt[1] = 0;
    for(int i = 2, j = 0; i <= m; i++) {
        while(j && s2[i] != s2[j+1]) j = nxt[j];
        if(s2[i] == s2[j+1]) j++;
        nxt[i] = j;
    }
    for(int i = 1, j = 0; i <= n; i++) {
        while(j && (j == m || s1[i] != s2[j+1])) j = nxt[j];
        if(s1[i] == s2[j+1]) j++;
        if(j == m) printf("%d\n", i-j+1);
    }
    for(int i = 1; i <= m; i++) printf("%d ", nxt[i]);
    return 0;
}

树状数组(fenwickTree)

fenwickTree

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 500010
#define ll long long
#define lowbit(x) ((x) & -(x))
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n, m;
int v[M];
inline void add(int x, int d) 
{
    while(x <= n) {
        v[x] += d;
        x += lowbit(x);
    }
    return;
}
inline int query(int x)
{
    int ret = 0;
    while(x) {
        ret += v[x];
        x -= lowbit(x);
    }
    return ret;
} 
int main() {
    n = read(), m = read();
    for(int i = 1; i <= n; i++) {
        int x = read();
        add(i, x);
    }
    for(int i = 1; i <= m; i++) {
        int opt = read();
        if(opt == 1) {
            int x = read(), d = read();
            add(x, d);
        }
        else {
            int x = read(), y = read();
            printf("%d\n", query(y) - query(x-1));
        }
    }
    return 0;
}

fenwickTree

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 500010
#define ll long long
#define lowbit(x) ((x) & -(x))
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n, m;
int v[M];
inline void add(int x, int d) 
{
    while(x <= n) {
        v[x] += d;
        x += lowbit(x);
    }
    return;
}
inline int query(int x)
{
    int ret = 0;
    while(x) {
        ret += v[x];
        x -= lowbit(x);
    }
    return ret;
} 
int main() {
    n = read(), m = read();
    int last = 0;
    for(int i = 1; i <= n; i++) {
        int x = read();
        add(i, x-last);
        last = x;
    }
    for(int i = 1; i <= m; i++) {
        int opt = read();
        if(opt == 1) {
            int x = read(), y = read(), d = read();
            add(x, d);
            add(y+1, -d);
        }
        else {
            int x = read();
            printf("%d\n", query(x));
        }
    }
    return 0;
}

线段树(segment Tree)

segment Tree

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define M 1000005
#define ll long long
#define Mid (l+r)>>1
inline ll read()
{
    ll x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct Tree{
    Tree *lc, *rc;
    ll x;
    ll lazyp, lazym;
}dizhi[M<<1], *root = &dizhi[0];
int t=1;
int n, m, p;
ll a[M];
inline void push_up(Tree *tree) {tree->x = (tree->lc->x + tree->rc->x) % p;}
inline void build(Tree *tree, int l, int r) 
{
    if(l == r) {
        tree->x = a[l];
        tree->lazym = 1;
        return;
    }
    int mid = Mid;
    tree->lazym = 1;
    tree->lc = &dizhi[t++];
    tree->rc = &dizhi[t++];
    build(tree->lc, l, mid);
    build(tree->rc, mid+1, r);
    push_up(tree);
}

inline void push_down(Tree *tree, int l, int r)
{
    if((tree->lazyp == 0 && tree->lazym == 1) || tree->lc == NULL) return;
    int mid = Mid;
    tree->lc->x = ((tree->lc->x * tree->lazym) % p + (ll)tree->lazyp * (mid - l + 1)) % p;
    tree->rc->x = ((tree->rc->x * tree->lazym) % p + (ll)tree->lazyp * (r - mid)) % p;
    tree->lc->lazym = (tree->lc->lazym * tree->lazym) % p;
    tree->rc->lazym = (tree->rc->lazym * tree->lazym) % p;
    tree->lc->lazyp = ((ll)tree->lc->lazyp * tree->lazym + tree->lazyp) % p;
    tree->rc->lazyp = ((ll)tree->rc->lazyp * tree->lazym + tree->lazyp) % p;
    tree->lazyp = 0;
    tree->lazym = 1;
    return;
}

inline void add(Tree *tree, int l, int r, int x, int y, int d)
{
    if(x <= l && y >= r) {
        tree->x = (tree->x + (ll) d * (r - l + 1)) % p;
        tree->lazyp = (tree->lazyp + d) % p;
        return;
    }
    push_down(tree, l, r);
    int mid = Mid;
    if(x <= mid) add(tree->lc, l, mid, x, y, d);
    if(y > mid) add(tree->rc, mid+1, r, x, y, d);
    push_up(tree);
}

inline void multi(Tree *tree, int l, int r, int x, int y, int d)
{
    if(x <= l && y >= r) {
        if(tree->lazyp) push_down(tree, l, r);
        tree->x = (tree->x * d) % p;
        tree->lazym = (tree->lazym * d) % p;
        return;
    }
    push_down(tree, l, r);
    int mid = Mid;
    if(x <= mid) multi(tree->lc, l, mid, x, y, d);
    if(y > mid) multi(tree->rc, mid+1, r, x, y, d);
    push_up(tree);
}

inline ll query(Tree *tree, int l, int r, int x, int y) 
{
    if(x <= l && y >= r) return tree->x;
    push_down(tree, l, r);
    int mid = Mid;
    ll ret = 0;
    if(x <= mid) ret = (ret + query(tree->lc, l, mid, x, y)) % p;
    if(y > mid) ret = (ret + query(tree->rc, mid+1, r, x, y));
    return ret % p;
}

int main() {
    n = read(), m = read(), p = read();
    for(int i = 1; i <= n; i++) a[i] = read();
    build(root, 1, n);
    for(int i = 1; i <= m; i++) {
        int opt = read();
        if(opt == 1) {
            int x = read(), y = read(), k = read();
            multi(root, 1, n, x, y, k);
        }
        else if(opt == 2) {
            int x = read(), y = read(), k = read();
            add(root, 1, n, x, y, k);
        }
        else {
            int x = read(), y = read();
            printf("%lld\n", query(root, 1, n, x, y));
        } 
    }
    return 0;
}

LCA

LCA

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
//Mystery_Sky
//
#define M 500010
#define ll long long
#define INF 0x7fffff
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct Edge{
    int to, next;
}edge[M<<3];
int cnt, head[M];
int n, m, s, t;
int d[M], vis[M], f[M][30];
inline void add_edge(int u, int v) {edge[++cnt].to = v; edge[cnt].next = head[u]; head[u] = cnt;}
queue <int> Q;
inline void bfs(int s)
{
    Q.push(s);
    d[s] = 1;
    vis[s] = 1;
    while(!Q.empty()) {
        int x = Q.front(); Q.pop();
        for(int i = head[x]; i; i = edge[i].next) {
            int y = edge[i].to;
            if(vis[y]) continue;
            vis[y] = 1;
            f[y][0] = x;
            d[y] = d[x] + 1;
            for(int i = 1; i <= t; i++)
                f[y][i] = f[f[y][i-1]][i-1];
            Q.push(y);
        }
    }
    return;
}
inline int LCA(int x, int y) 
{
    if(d[x] > d[y]) swap(x, y);
    for(int i = t; i >= 0; i--) 
        if(d[f[y][i]] >= d[x]) y = f[y][i];
    if(x == y) return x;
    for(int i = t; i >= 0; i--)
        if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
    return f[x][0]; 
}
int main() {
    n = read(), m = read(), s = read();
    t = (int)(log(n) / log(2));
    for(int i = 1; i <= n-1; i++) {
        int u = read(), v = read();
        add_edge(u, v);
        add_edge(v, u);
    }
    bfs(s);
    for(int i = 1; i <= m; i++) {
        int a = read(), b = read();
        printf("%d\n", LCA(a, b));
    }
    return 0;
}

分块

分块

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
//Mystery_Sky
//
#define M 1000100
#define INF 0x3f3f3f3f
#define ll long long
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n, m, blo;
ll bl[M], sum[M], atag[M];
ll v[M];
inline void add(ll l, ll r, ll d)
{
    for(int i = l; i <= min(r, bl[l]*blo); i++) {
        v[i] += d;
        sum[bl[i]] += d;
    }
    if(bl[l] != bl[r])
        for(int i = (bl[r]-1)*blo+1; i <= r; i++) {
            v[i] += d;
            sum[bl[i]] += d;
        }
     for(int i = bl[l]+1; i < bl[r]; i++)
        atag[i] += d;
     return ;
}
inline ll query(ll l, ll r)
{
    ll ans = 0;
    for(int i = l; i <= min(r, bl[l]*blo); i++) ans += (v[i] + atag[bl[i]]);
    if(bl[l] != bl[r])
        for(int i = (bl[r]-1)*blo+1; i <= r; i++) ans += (v[i] + atag[bl[i]]);
    for(int i = bl[l]+1; i < bl[r]; i++)
        ans += (sum[i] + blo * atag[i]);
    return ans;
}
int main() {
    n = read(), m = read();
    blo = sqrt(n);
    for(int i = 1; i <= n; i++) v[i] = read(), bl[i] = (i-1)/blo+1, sum[bl[i]] += v[i];
    for(int i = 1; i <= m; i++) {
        int opt = read();
        if(opt == 1) {
            int x = read(), y = read(), d = read();
            add(x, y, d);    
        }
        else {
            int x = read(), y = read();
            printf("%lld\n", query(x, y));
        }
    }
    return 0;
}

欧拉筛

欧拉筛

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
//Mystery_Sky
//prime[]建议用数组,用vector会慢很多 || 1.04s(数组) —— 2.02s(vector)
#define INF 0x3f3f3f3f
#define M 10000010
#define ll long long
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n, m;
int check[M];
vector <int> prime;
inline void get_prime()
{
    prime.push_back(0);
    check[1] = 1;
    check[0] = 1;
    for(int i = 2; i <= n; i++) {
        if(!check[i]) prime.push_back(i), prime[0]++;
        for(int j = 1; j <= prime[0]; j++) {
            if(i * prime[j] > n) break;
            check[i*prime[j]] = 1;
            if(i % prime[j] == 0) break;
        }
    }
}
int main() {
    n = read(), m = read();
    get_prime();
    for(int i = 1; i <= m; i++) {
        int x = read();
        if(check[x]) printf("No\n");
        else printf("Yes\n"); 
    }
    return 0;
}

扩展欧几里德

扩欧

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
//Mystery_Sky
//
#define INF 0x3f3f3f3f
#define ll long long
inline ll read()
{
    ll x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
ll a, b, x, y, d;
ll exgcd(ll a, ll b, ll &x, ll &y, ll &d)
{
    if(!b) {d = a, x = 1, y = 0;}
    else {
        exgcd(b, a%b, y, x, d);
        y -= x * (a / b);
    }
}
int main() {
    a = read(), b = read();
    exgcd(a, b, x, y, d);
    printf("%lld\n", (x + b) % b);
    return 0;
}
posted @ 2019-11-15 07:18  Mystery_Sky  阅读(660)  评论(1编辑  收藏  举报