模板复习【updating】

马上就要noi了……可能滚粗已经稳了……但是还是要复习模板啊

LCT: bzoj2049 1A 7min

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;

struct LCT {
    int ch[M][2], fa[M], sz[M]; bool rev[M];
    # define ls ch[x][0]
    # define rs ch[x][1]
    inline void up(int x) {
        if(!x) return ;
        sz[x] = 1 + sz[ls] + sz[rs];
    }
    inline void pushrev(int x) {
        if(!x) return ;
        rev[x] ^= 1;
        swap(ch[x][0], ch[x][1]);
    }
    inline void down(int x) {
        if(!x) return ;
        if(rev[x]) {
            pushrev(ls);
            pushrev(rs);
            rev[x] = 0;
        }
    }
    # undef ls
    # undef rs
    inline bool isrt(int x) {
        return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
    }
    inline void rotate(int x) {
        int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1;
        if(!isrt(y)) ch[z][ch[z][1] == y] = x;
        fa[ch[x][rs]] = y; fa[y] = x, fa[x] = z;
        ch[y][ls] = ch[x][rs]; ch[x][rs] = y;
        up(y); up(x);
    }
    int st[M];
    inline void splay(int x) {
        int stn = 0, tx = x;
        while(!isrt(tx)) st[++stn] = tx, tx = fa[tx];
        st[++stn] = tx;
        for (int i=stn; i; --i) down(st[i]);
        while(!isrt(x)) {
            int y = fa[x], z = fa[y];
            if(!isrt(y)) {
                if((ch[z][0] == y) ^ (ch[y][0] == x)) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    inline int access(int x) {
        int t = 0;
        for (; x; t=x, x=fa[x]) {
            splay(x);
            ch[x][1] = t;
            up(x);
        }
        return t;
    }
    inline void makeroot(int x) {
        access(x); splay(x); pushrev(x);
    }
    inline int find(int x) {
        access(x); splay(x);
        while(ch[x][0]) x = ch[x][0];
        return x;
    }
    inline void link(int x, int y) {
        makeroot(x); fa[x] = y;
    }
    inline void cut(int x, int y) {
        makeroot(x); access(y); splay(y); ch[y][0] = fa[x] = 0; up(y);
    }
}T;

int n, Q, x, y;

int main() {
    static char op[23];
    cin >> n >> Q;
    for (int i=1; i<=n; ++i) {
        T.ch[i][0] = T.ch[i][1] = T.fa[i] = 0;
        T.sz[i] = 1; T.rev[i] = 0;
    }
    while(Q--) {
        scanf("%s%d%d", op, &x, &y);
        if(op[0] == ‘C‘) T.link(x, y);
        else if(op[0] == ‘D‘) T.cut(x, y);
        else puts(T.find(x) == T.find(y) ? "Yes" : "No");
    }
    return 0;
}

dsu on tree: bzoj4756 1A 10min

# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 1e5 + 10;
const int mod = 1e9+7;

int n, a[N];
vector<int> ps;
int head[N], nxt[N], to[N], tot = 0;
inline void add(int u, int v) {
    ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
}

struct BIT {
    int n, c[N];
    # define lb(x) (x & (-x))
    inline void set(int _n) {
        n = _n;
        memset(c, 0, sizeof c);
    }
    inline void edt(int x, int d) {
        for (; x<=n; x+=lb(x)) c[x] += d;
    }
    inline int sum(int x) {
        int ret = 0;
        for (; x; x-=lb(x)) ret += c[x];
        return ret;
    }
    inline int sum(int x, int y) {
        if(x > y) return 0;
        return sum(y) - sum(x-1);
    }
    # undef lb
}T;

int sz[N], mx[N];
inline void dfs(int x) {
    sz[x] = 1; mx[x] = 0;
    for (int i=head[x]; i; i=nxt[i]) {
        dfs(to[i]);
        sz[x] += sz[to[i]];
        if(mx[x] == 0 || sz[to[i]] > sz[mx[x]]) mx[x] = to[i];
    }
}

int ans[N], big[N];

inline void count(int x, int p) {
    T.edt(a[x], p);
    for (int i=head[x]; i; i=nxt[i])
        if(!big[to[i]]) count(to[i], p);
}

inline void dsu(int x, bool kep = 0) {
    int son = mx[x];
    for (int i=head[x]; i; i=nxt[i])
        if(to[i] != son) dsu(to[i], 0);
    if(son) big[son] = 1, dsu(son, 1);
    count(x, 1);
    ans[x] = T.sum(a[x] + 1, n);
    if(son) big[son] = 0;
    if(!kep) count(x, -1);
}

int main() {
    cin >> n; T.set(n);
    for (int i=1; i<=n; ++i) {
        scanf("%d", a+i);
        ps.push_back(a[i]);
    }
    sort(ps.begin(), ps.end());
    ps.erase(unique(ps.begin(), ps.end()), ps.end());
    for (int i=1; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + 1;
    for (int i=2, par; i<=n; ++i) {
        scanf("%d", &par);
        add(par, i);
    }
    dfs(1);
    dsu(1);
    for (int i=1; i<=n; ++i) printf("%d\n", ans[i]);
    return 0;
}

线段树合并: bzoj4756 2A 13min

warning: 需要注意节点数量为$O(nlogn)$。

# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 1e5 + 10, SN = 262144 * 20 + 5;
const int mod = 1e9+7;

int n, a[N];
vector<int> ps;
int head[N], nxt[N], to[N], tot = 0;
inline void add(int u, int v) {
    ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
}

int rt[N];
struct SMT {
    int siz;
    int s[SN], ch[SN][2];
    # define ls ch[x][0]
    # define rs ch[x][1]
    inline void set() {
        siz = 0;
        memset(ch, 0, sizeof ch);
        memset(s, 0, sizeof s);
    }
    inline void up(int x) {
        if(!x) return;
        s[x] = s[ls] + s[rs];
    }
    inline void edt(int &x, int l, int r, int ps, int d) {
        if(!x) x = ++siz;
        if(l == r) {
            s[x] = 1;
            return;
        }
        int mid = l+r>>1;
        if(ps <= mid) edt(ls, l, mid, ps, d);
        else edt(rs, mid+1, r, ps, d);
        up(x);
    }
    inline int sum(int x, int l, int r, int L, int R) {
        if(!x || L>R) return 0;
        if(L <= l && r <= R) return s[x];
        int mid = l+r>>1, ret = 0;
        if(L <= mid) ret += sum(ls, l, mid, L, R);
        if(R > mid) ret += sum(rs, mid+1, r, L, R);
        return ret;
    }
    inline int merge(int x, int y, int l, int r) {
        if(!x || !y) return x+y;
        if(l == r) {
            s[x] += s[y];
            return x;
        }
        int mid = l+r>>1;
        ls = merge(ch[x][0], ch[y][0], l, mid);
        rs = merge(ch[x][1], ch[y][1], mid+1, r);
        up(x);
        return x;
    }
}T;

int ans[N];
inline void dfs(int x) {
    for (int i=head[x]; i; i=nxt[i]) {
        dfs(to[i]);
        rt[x] = T.merge(rt[x], rt[to[i]], 1, n);
    }
    ans[x] = T.sum(rt[x], 1, n, a[x] + 1, n);
}

int main() {
    cin >> n; T.set();
    for (int i=1; i<=n; ++i) {
        scanf("%d", a+i);
        ps.push_back(a[i]);
    }
    sort(ps.begin(), ps.end());
    ps.erase(unique(ps.begin(), ps.end()), ps.end());
    for (int i=1; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + 1;
    for (int i=2, par; i<=n; ++i) {
        scanf("%d", &par);
        add(par, i);
    }
    for (int i=1; i<=n; ++i) T.edt(rt[i], 1, n, a[i], 1);

    dfs(1);

    for (int i=1; i<=n; ++i) printf("%d\n", ans[i]);
    return 0;
}

线段树:codevs4927 2A 8min

warning: 区间覆盖后线清空tag标记,然后再传下来的tag标记是在cov之后的,所以要先传cov再传tag

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

# ifdef WIN32
# define LLD "%I64d"
# else
# define LLD "%lld"
# endif

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 1e5 + 10, SN = 262144 + 5;
const int mod = 1e9+7;

int n, m;
ll a[N];

struct SMT {
    ll s[SN], mx[SN], mi[SN], tag[SN], cov[SN]; bool hc[SN];
    # define ls (x<<1)
    # define rs (x<<1|1)
    inline void up(int x) {
        s[x] = s[ls] + s[rs];
        mx[x] = max(mx[ls], mx[rs]);
        mi[x] = min(mi[ls], mi[rs]);
    }
    inline void pushtag(int x, int l, int r, ll tg) {
        tag[x] += tg; s[x] += tg*(r-l+1);
        mx[x] += tg, mi[x] += tg;
    }
    inline void pushcov(int x, int l, int r, ll tg) {
        tag[x] = 0; hc[x] = 1; cov[x] = tg;
        mx[x] = mi[x] = tg; s[x] = tg * (r-l+1);
    }
    inline void down(int x, int l, int r) {
        int mid = l+r>>1;
        if(hc[x]) {
            pushcov(ls, l, mid, cov[x]);
            pushcov(rs, mid+1, r, cov[x]);
            cov[x] = hc[x] = 0;
        }
        if(tag[x]) {
            pushtag(ls, l, mid, tag[x]);
            pushtag(rs, mid+1, r, tag[x]);
            tag[x] = 0;
        }
    }
    inline void build(int x, int l, int r) {
        tag[x] = cov[x] = hc[x] = 0;
        if(l == r) {
            mx[x] = mi[x] = s[x] = a[l];
            return ;
        }
        int mid = l+r>>1;
        build(ls, l, mid); build(rs, mid+1, r);
        up(x);
    }
    inline void edt(int x, int l, int r, int L, int R, ll p) {
        if(L <= l && r <= R) {
            pushtag(x, l, r, p);
            return ;
        }
        down(x, l, r);
        int mid = l+r>>1;
        if(L <= mid) edt(ls, l, mid, L, R, p);
        if(R > mid) edt(rs, mid+1, r, L, R, p);
        up(x);
    }
    inline void cover(int x, int l, int r, int L, int R, ll p) {
        if(L <= l && r <= R) {
            pushcov(x, l, r, p);
            return ;
        }
        down(x, l, r);
        int mid = l+r>>1;
        if(L <= mid) cover(ls, l, mid, L, R, p);
        if(R > mid) cover(rs, mid+1, r, L, R, p);
        up(x);
    }
    inline ll sum(int x, int l, int r, int L, int R) {
        if(L <= l && r <= R) return s[x];
        down(x, l, r);
        int mid = l+r>>1; ll ret = 0;
        if(L <= mid) ret += sum(ls, l, mid, L, R);
        if(R > mid) ret += sum(rs, mid+1, r, L, R);
        return ret;
    }
    inline ll gmax(int x, int l, int r, int L, int R) {
        if(L <= l && r <= R) return mx[x];
        down(x, l, r);
        int mid = l+r>>1;
        if(R <= mid) return gmax(ls, l, mid, L, R);
        else if(L > mid) return gmax(rs, mid+1, r, L, R);
        else return max(gmax(ls, l, mid, L, R), gmax(rs, mid+1, r, L, R));
    }
    inline ll gmin(int x, int l, int r, int L, int R) {
        if(L <= l && r <= R) return mi[x];
        down(x, l, r);
        int mid = l+r>>1;
        if(R <= mid) return gmin(ls, l, mid, L, R);
        else if(L > mid) return gmin(rs, mid+1, r, L, R);
        else return min(gmin(ls, l, mid, L, R), gmin(rs, mid+1, r, L, R));
    }
}T;

int main() {
    register int Q, x, y, z;
    register char op[23];
    cin >> n >> Q;
    for (int i=1; i<=n; ++i) scanf(LLD, a+i);
    T.build(1, 1, n);
    while(Q--) {
        scanf("%s%d%d", op, &x, &y);
        if(op[1] == ‘d‘) {
            scanf(LLD, &z);
            T.edt(1, 1, n, x, y, z);
        }
        else if(op[1] == ‘e‘) {
            scanf(LLD, &z);
            T.cover(1, 1, n, x, y, z);
        }
        else if(op[1] == ‘u‘) printf(LLD "\n", T.sum(1, 1, n, x, y));
        else if(op[1] == ‘a‘) printf(LLD "\n", T.gmax(1, 1, n, x, y));
        else printf(LLD "\n", T.gmin(1, 1, n, x, y));
    }
    return 0;
}

时间: 2024-11-08 22:14:45

模板复习【updating】的相关文章

强连通分量tarjan模板复习

对于一个有向图定点的子集,在该子集中任取两点u与v,都能找到一条从u到v的路径,则称该子集是强连通的.若该集合加入到任意点集中,它都不再强连通,则称这个子集是原图的一个强连通分量.任意一张图都可以分解成若干个不相交的强连通分量.这是强连通分量分解.把分解后的强连通分量缩成一个顶点,就可以得到一个有向无环图. 如图: 求一张图的强连通分量的个数,常用tarjan算法,它是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈

C++函数模板复习

#include <iostream> #include <typeinfo> using namespace std; template <class T> T add(T one, T two) { cout << "类型:" << typeid(T).name() << endl; return one + two; // 函数模板只有在调用时才编译,有的编译器在初次编译时就会编译 } int add(int

省选前模板复习

PREFACE 也许是OI生涯最后一场正式比赛了,说是省选前模板,其实都是非常基础的东西,穿插了英文介绍和部分代码实现 祝各位参加JXOI2019的都加油吧 也希望今年JX能翻身,在国赛中夺金 数学知识 见数学知识小结 字符串 KMP算法Knuth-Morris-Pratt Algorithm KMP算法,又称模式匹配算法,是用来在一个文本串(text string)s中找到所有模式串(pattern)w出现的位置. 它是通过当失配(mismatch)发生时,模式串本身能提供足够的信息来决定下一

c++异常模板复习

1 // ConsoleApplication1.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 #include"TEST2.h" 7 #include<exception> 8 using namespace std; 9 using std::cout; using std::endl; 10 11 template<typename

模板复习计划

20161111 BZOJ3224 普通平衡树|treap //BZOJ 3224 //by Cydiater //2016.11.11 #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <ctime> #include <cmat

hdu 1863 [【最小生成树】+hdu2544【floyed】+hdu1874【dijdtra】~~~模板复习~~~

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863 #include<stdio.h> #include<string.h> #define inf 0x3f3f3f3f #define N 120 int book[N],w[N][N],min,dis[N]; int main() {     int m,n,i,j,t1,t2,t3,s,e,u,flag,sum;     while(scanf("%d%d"

模板复习

并查集 1 /* 2 problem:fuxi 3 date:2019/5/26 4 author:Lonely.Devil 5 */ 6 7 #include<iostream> 8 #include<cstdio> 9 #include<cstring> 10 using namespace std; 11 const int maxn = 1e5+5; 12 int father[maxn]; 13 int n,m; 14 inline int find(int

线段树简单操作模板复习(忘了。)

// 参考博客 https://www.cnblogs.com/TheRoadToTheGold/p/6254255.html#4175712 // 懒人标记: 表示当前结点区间值已经改变,但是下面的区间还没改变.每次询问到有懒人标记的结点时,在进一步询问他的子节点时,下放标记(下放的同时改变了子结点的值,并且赋予子节点懒人标记)// 因此 当将要查询对应区间时候 之前修改区间的操作在此时才进行 -- 因此叫懒人标记 1 #include<cstdio> 2 using namespace s

复习啦。。

模板复习计划.图论:最短路:Dijkstra SPFA Floyed最小圈(*) 二维Dijkstra.SPFA倍增Floyed(*)最小生成树,各种生成树(里面有些还不会) 最小树形图二分图:各种概念,二分图最大权匹配(KM), HC算法(*)网络流:(把所有建模都看一遍,,,不管会不会的)费用流(最小/大费用最大流) ZKW费用流(*)最大流上下界网络流 动态规划:树型Dp(*).数位Dp决策单调性(*)插头DP斯坦纳树(*)记忆化搜索 字符串:后缀自动机.AC自动机.回文自动机,字符串 +