NOIP2018赛前模板复习

线段树

/************************************************
*Author        :  lrj124
*Created Time  :  2018.11.05.16:31
*Mail          :  [email protected]
*Problem       :  seg
************************************************/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 10;
int n,m;
struct seg {
    long long sum;
    int l,r,mark;
}tree[maxn<<2];
inline void pushup(int root) { tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum; }
inline void pushdown(int root) {
    if (tree[root].mark) {
        tree[root<<1].mark += tree[root].mark;
        tree[root<<1].sum += tree[root].mark*(tree[root<<1].r-tree[root<<1].l+1);
        tree[root<<1|1].mark += tree[root].mark;
        tree[root<<1|1].sum += tree[root].mark*(tree[root<<1|1].r-tree[root<<1|1].l+1);
        tree[root].mark = 0;
    }
}
inline void build(int l,int r,int root) {
    tree[root].l = l;
    tree[root].r = r;
    if (l == r) {
        scanf("%lld",&tree[root].sum);
        return;
    }
    int mid = l+r>>1;
    build(l,mid,root<<1);
    build(mid+1,r,root<<1|1);
    pushup(root);
}
inline void update(int l,int r,int ql,int qr,int root,long long x) {
    if (r < ql || l > qr) return;
    if (ql <= l && r <= qr) {
        tree[root].sum += x*(r-l+1);
        tree[root].mark += x;
        return;
    }
    pushdown(root);
    int mid = l+r>>1;
    update(l,mid,ql,qr,root<<1,x);
    update(mid+1,r,ql,qr,root<<1|1,x);
    pushup(root);
}
inline long long query(int l,int r,int ql,int qr,int root) {
    if (r < ql || l > qr) return 0;
    if (ql <= l && r <= qr) return tree[root].sum;
    pushdown(root);
    int mid = l+r>>1;
    return query(l,mid,ql,qr,root<<1)+query(mid+1,r,ql,qr,root<<1|1);
}
int main() {
    //freopen("seg.in","r",stdin);
    //freopen("seg.out","w",stdout);
    scanf("%d%d",&n,&m);
    build(1,n,1);
    while (m--) {
        int op,l,r;
        long long x;
        scanf("%d%d%d",&op,&l,&r);
        if (op == 1) {
            scanf("%lld",&x);
            update(1,n,l,r,1,x);
        } else printf("%lld\n",query(1,n,l,r,1));
    }
    //cerr << 1.0*clock()/CLOCKS_PER_SEC << endl;
    return 0;
}

树链剖分

/************************************************
*Author        :  lrj124
*Created Time  :  2018.11.05.17:03
*Mail          :  [email protected]
*Problem       :  tcd
************************************************/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 10;
int cnt,n,m,rt,p,val[maxn],dep[maxn],father[maxn],top[maxn],size[maxn],son[maxn],Map[maxn],num[maxn];
vector<int> edge[maxn];
inline void dfs1(int now,int fa) {
    dep[now] = dep[fa]+1;
    father[now] = fa;
    size[now] = 1;
    for (size_t i = 0;i < edge[now].size();i++)
        if (edge[now][i] != fa) {
            dfs1(edge[now][i],now);
            size[now] += size[edge[now][i]];
            if (size[edge[now][i]] > size[son[now]]) son[now] = edge[now][i];
        }
}
inline void dfs2(int now,int ntop) {
    num[now] = ++cnt;
    Map[num[now]] = now;
    top[now] = ntop;
    if (son[now]) dfs2(son[now],ntop);
    for (size_t i = 0;i < edge[now].size();i++)
        if (edge[now][i] != father[now] && edge[now][i] != son[now]) dfs2(edge[now][i],edge[now][i]);
}
struct seg { long long sum,l,r,mark; } tree[maxn<<2];
inline void pushup(int root) { tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum; }
inline void pushdown(int root) {
    if (tree[root].mark) {
        tree[root<<1].mark += tree[root].mark;
        tree[root<<1|1].mark += tree[root].mark;
        tree[root<<1].sum += tree[root].mark*(tree[root<<1].r-tree[root<<1].l+1);
        tree[root<<1|1].sum += tree[root].mark*(tree[root<<1|1].r-tree[root<<1|1].l+1);
        tree[root].mark = 0;
    }
}
inline void build(int l,int r,int root) {
    tree[root].l = l;
    tree[root].r = r;
    if (l == r) {
        tree[root].sum = val[Map[l]];
        return;
    }
    int mid = l+r>>1;
    build(l,mid,root<<1);
    build(mid+1,r,root<<1|1);
    pushup(root);
}
inline void update(int l,int r,int ql,int qr,int root,int x) {
    if (r < ql || l > qr) return;
    if (ql <= l && r <= qr) {
        tree[root].sum += x*(r-l+1);
        tree[root].mark += x;
        return;
    }
    pushdown(root);
    int mid = l+r>>1;
    update(l,mid,ql,qr,root<<1,x);
    update(mid+1,r,ql,qr,root<<1|1,x);
    pushup(root);
}
inline long long query(int l,int r,int ql,int qr,int root) {
    if (r < ql || l > qr) return 0;
    if (ql <= l && r <= qr) return tree[root].sum;
    int mid = l+r>>1;
    pushdown(root);
    return query(l,mid,ql,qr,root<<1)+query(mid+1,r,ql,qr,root<<1|1);
}
inline void updateroad(int u,int v,long long x) {
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u,v);
        update(1,n,num[top[u]],num[u],1,x);
        u = father[top[u]];
    }
    if (dep[u] > dep[v]) swap(u,v);
    update(1,n,num[u],num[v],1,x);
}
inline long long queryroad(int u,int v) {
    long long sum = 0;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u,v);
        sum = (sum+query(1,n,num[top[u]],num[u],1))%p;
        u = father[top[u]];
    }
    if (dep[u] > dep[v]) swap(u,v);
    return (sum+query(1,n,num[u],num[v],1))%p;
}
int main() {
    //freopen("tcd.in","r",stdin);
    //freopen("tcd.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&rt,&p);
    for (int i = 1;i <= n;i++) scanf("%d",&val[i]);
    for (int i = 1,u,v;i < n;i++) {
        scanf("%d%d",&u,&v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs1(rt,0);
    dfs2(rt,rt);
    build(1,n,1);
    while (m--) {
        int op,u,v;
        long long w;
        scanf("%d%d",&op,&u);
        if (op == 1) {
            scanf("%d%lld",&v,&w);
            updateroad(u,v,w);
        }
        if (op == 2) {
            scanf("%d",&v);
            printf("%lld\n",queryroad(u,v));
        }
        if (op == 3) {
            scanf("%lld",&w);
            update(1,n,num[u],num[u]+size[u]-1,1,w);
        }
        if (op == 4) printf("%lld\n",query(1,n,num[u],num[u]+size[u]-1,1)%p);
    }
    //cerr << 1.0*clock()/CLOCKS_PER_SEC << endl;
    return 0;
}

Splay

......

LCT

......

Dinic

......

匈牙利

......

扩展欧几里德

......

Dijkstra

......

KMP

......

LCA

......

莫队

......

猜你喜欢

转载自www.cnblogs.com/lrj124/p/9916603.html
今日推荐