zoukankan      html  css  js  c++  java
  • 模板复习

    Hihocoder KMP

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 1000005;
    
    char s[maxn], T[maxn];
    int len_s, len_t, cnt, N;
    int nxt[maxn];
    
    void Getnxt(){
            nxt[0] = -1;
            int i = 0, t = -1;
            while(i < len_s)
                    if(t == -1 || s[i] == s[t]) nxt[++ i] = ++ t; //  "==" --> "!="
                    else t = nxt[t];
    }
    
    void KMP(){
            int t1 = 0, t2 = 0;
            while(t2 < len_t)
                    if(t1 == -1 || s[t1] == t[t2]){
                            t1 ++, t2 ++; 
                            if(t1 == len_s){ 
                                    t1 = nxt[t1]; 
                                    cnt ++;
                            }
                    }else t1 = nxt[t1];
    }
    
    void Work(){
            scanf("%s%s", s, T);
            len_s = strlen(s), len_t = strlen(T);
            Getnxt();
            cnt = 0;
            KMP();
            printf("%d
    ", cnt);
    }
    
    int main(){
            scanf("%d", &N);
            while(N --) Work();
            return 0;
    }
    

    Hihocoder #1077 : RMQ问题再临-线段树 线段树单点修改, 区间最小值

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 1e6 + 10;
    
    int N, M;
    int Ql, Qr;
    
    struct Node{
            int v, l, r, min_v;
    } T[maxn<<2];
    
    void Build(int k, int l, int r){
            T[k].l = l, T[k].r = r;
            if(l == r){
                    scanf("%d", &T[k].v), T[k].min_v = T[k].v;
                    return ;
            }
            int mid = l+r >> 1;
            Build(k<<1, l, mid), Build(k<<1|1, mid+1, r);
            T[k].min_v = std::min(T[k<<1].min_v, T[k<<1|1].min_v);
    }
    
    int Query(int k){
            int l = T[k].l, r = T[k].r;
            if(Ql <= l && r <= Qr) return T[k].min_v;
            int mid = l+r >> 1;
            if(mid < Ql) return Query(k<<1|1);
            else if(mid >= Qr) return Query(k<<1);
            return std::min(Query(k<<1|1), Query(k<<1));
    }
    
    void Modify(int k){
            int l = T[k].l, r = T[k].r;
            if(l == r){
                    T[k].min_v = T[k].v = Qr;
                    return ;
            }
            int mid = l+r >> 1;
            if(Ql <= mid) Modify(k<<1);
            else Modify(k<<1|1);
            T[k].min_v = std::min(T[k<<1].min_v, T[k<<1|1].min_v);
    }
    
    int main(){
            scanf("%d", &N);
            Build(1, 1, N);
            scanf("%d", &M);
            int opt;
            while(M --){
                    scanf("%d%d%d", &opt, &Ql, &Qr);
                    if(!opt){
                            int Ans = Query(1);
                            printf("%d
    ", Ans);
                    }
                    else Modify(1);
            }
            return 0;
    }
    

    P3372 【模板】线段树 1线段树区间修改, 区间和

    注意标记的加值

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 1e6 + 10;
    
    typedef long long ll;
    
    int N, M;
    int Ql, Qr;
    ll Qv;
    int tag[maxn<<2];
    
    struct Node{
            ll v, min_v, sum;
            int l, r;
    } T[maxn<<2];
    
    void Build(int k, int l, int r){
            T[k].l = l, T[k].r = r;
            if(l == r){
                    scanf("%lld", &T[k].v), T[k].min_v = T[k].v, T[k].sum = T[k].v;
                    return ;
            }
            int mid = l+r >> 1;
            Build(k<<1, l, mid), Build(k<<1|1, mid+1, r);
            T[k].min_v = std::min(T[k<<1].min_v, T[k<<1|1].min_v);
            T[k].sum = T[k<<1].sum + T[k<<1|1].sum;
    }
    
    void Push_down(int k){
            int l, r;
            tag[k<<1] += tag[k], tag[k<<1|1] += tag[k];
            l = T[k<<1].l, r = T[k<<1].r;
            T[k<<1].sum += 1ll*(r - l + 1) * tag[k];
            l = T[k<<1|1].l, r = T[k<<1|1].r;
            T[k<<1|1].sum += 1ll*(r - l + 1) * tag[k];
            tag[k] = 0;
    }
    
    void Modify_2(int k){
            int l = T[k].l, r = T[k].r;
            if(Ql <= l && r <= Qr){
                    T[k].sum += 1ll*(r-l+1)*Qv;
                    tag[k] += Qv;
                    return ;
            }
            if(tag[k]) Push_down(k);
            int mid = l+r >> 1;
            if(mid < Ql) Modify_2(k<<1|1);
            else if(mid >= Qr) Modify_2(k<<1);
            else Modify_2(k<<1), Modify_2(k<<1|1);
            T[k].sum = T[k<<1].sum + T[k<<1|1].sum;
    }
    
    ll Query_2(int k){
            int l = T[k].l, r = T[k].r;
            if(Ql <= l && r <= Qr) return T[k].sum;
            if(tag[k]) Push_down(k);
            ll tmp = 0;
            int mid = l+r >> 1;
            if(mid < Ql) tmp += Query_2(k<<1|1);
            else if(mid >= Qr) tmp += Query_2(k<<1);
            else tmp += Query_2(k<<1) + Query_2(k<<1|1);
            T[k].sum = T[k<<1].sum + T[k<<1|1].sum;
            return tmp;
    }
    
    int main(){
            scanf("%d%d", &N, &M);
            Build(1, 1, N);
            int opt;
            while(M --){
                    scanf("%d%d%d", &opt, &Ql, &Qr);
                    if(opt == 1){
                            scanf("%lld", &Qv);
                            Modify_2(1);
                    }else{
                            ll Ans = Query_2(1);
                            printf("%lld
    ", Ans);
                    }
            }
            return 0;
    }
    

    树链剖分

    注意Dfn序和原编号的区别

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 1e5+10;
    
    int N, M, R, P;
    int head[maxn], size[maxn], max_son[maxn], max_w[maxn];
    int top[maxn], dfn[maxn], Fa[maxn], dep[maxn], w[maxn], max_num[maxn];
    int tim, num0;
    
    namespace Seg{
    
            struct Node{
                    int v, l, r, tag;
            } T[maxn<<2];
    
            void Build(int k, int l, int r){
                    T[k].l = l, T[k].r = r;
                    if(l == r){
                            T[k].v = T[k].tag = 0;
                            return ;
                    }
                    int mid = l+r >> 1;
                    Build(k<<1, l, mid), Build(k<<1|1, mid+1, r);
                    T[k].v = (1ll*T[k<<1].v + T[k<<1|1].v) % P;
            }
    
            void Push_down(int k){
                    T[k<<1].tag = (1ll*T[k<<1].tag + T[k].tag) % P;
                    T[k<<1|1].tag = (1ll*T[k<<1|1].tag + T[k].tag) % P;
                    int l, r;
                    l = T[k<<1].l, r = T[k<<1].r;
                    T[k<<1].v = (1ll*T[k<<1].v + (1ll*T[k].tag*(r - l + 1) % P)) % P;
                    l = T[k<<1|1].l, r = T[k<<1|1].r;
                    T[k<<1|1].v = (1ll*T[k<<1|1].v + (1ll*T[k].tag*(r - l + 1) % P)) % P;
                    T[k].tag = 0;
            }
    
            void Modify(int k, const int &Ql, const int &Qr, const int &v){
                    int l = T[k].l, r = T[k].r;
                    if(Ql <= l && r <= Qr){
                            T[k].v += 1ll*v*(r - l + 1) % P;
                            T[k].tag = (1ll*T[k].tag + v) % P;
                            return ;
                    }
                    if(T[k].tag) Push_down(k);
                    int mid = l+r >> 1;
                    if(mid < Ql) Modify(k<<1|1, Ql, Qr, v);
                    else if(mid >= Qr) Modify(k<<1, Ql, Qr, v);
                    else Modify(k<<1, Ql, Qr, v), Modify(k<<1|1, Ql, Qr, v);
                    T[k].v = (1ll*T[k<<1].v + T[k<<1|1].v) % P;
            }
    
            int Query(int k, const int &Ql, const int &Qr){
                    int l = T[k].l, r = T[k].r;
                    if(Ql <= l && r <= Qr) return T[k].v;
                    if(T[k].tag) Push_down(k);
                    int mid = l+r >> 1;
                    T[k].v = (1ll*T[k<<1].v + T[k<<1|1].v) % P;
                    if(mid < Ql) return Query(k<<1|1, Ql, Qr);
                    else if(mid >= Qr) return Query(k<<1, Ql, Qr);
                    return (1ll*Query(k<<1|1, Ql, Qr) + Query(k<<1, Ql, Qr)) % P;
            }
    
    }
    
    struct Edge{ int nxt, to; } edge[maxn<<1];
    
    void Add(int from, int to){
            edge[++ num0] = (Edge){ head[from], to };
            head[from] = num0;
    }
    
    void DFS_1(int k, int fa){
            size[k] = 1;
            max_son[k] = 0, max_w[k] = 0;
            dep[k] = dep[fa] + 1;
            Fa[k] = fa;
            for(reg int i = head[k]; i; i = edge[i].nxt){
                    int to = edge[i].to;
                    if(to == fa) continue ;
                    DFS_1(to, k);
                    size[k] += size[to];
                    if(size[to] > max_w[k]){
                            max_w[k] = size[to];
                            max_son[k] = to;
                    }
            }
    }
    
    void DFS_2(int k, int fa){
            dfn[k] = ++ tim;
            Seg::Modify(1, dfn[k], dfn[k], w[k]);
            top[k] = fa;
            if(max_son[k]) DFS_2(max_son[k], fa);
            for(reg int i = head[k]; i; i = edge[i].nxt){
                    int to = edge[i].to;
                    if(dfn[to]) continue ;
                    DFS_2(to, to);
            }
            max_num[k] = tim;
    }
    
    void Modify_P(int x, int y, int z){
            while(top[x] != top[y]){
                    if(dep[top[x]] < dep[top[y]]) std::swap(x, y);
                    Seg::Modify(1, dfn[top[x]], dfn[x], z);
                    x = Fa[top[x]];
            }
            if(dfn[x] > dfn[y]) std::swap(x, y);
            Seg::Modify(1, dfn[x], dfn[y], z);
    }
    
    int Query_P(int x, int y){
            int res = 0;
            while(top[x] != top[y]){
                    if(dep[top[x]] < dep[top[y]]) std::swap(x, y);
                    res = (1ll*res+Seg::Query(1, dfn[top[x]], dfn[x])) % P;
                    x = Fa[top[x]];
            }
            if(dfn[x] > dfn[y]) std::swap(x, y);
            res = (1l*res + Seg::Query(1, dfn[x], dfn[y])) % P;
            return res;
    }
    
    void Work(){
            int opt, x, y, z;
            scanf("%d", &opt);
            if(opt == 1){
                    scanf("%d%d%d", &x, &y, &z);
                    Modify_P(x, y, z);
            }else if(opt == 2){
                    scanf("%d%d", &x, &y);
                    int Ans = Query_P(x, y);
                    printf("%d
    ", Ans);
            }else if(opt == 3){
                    scanf("%d%d", &x, &z);
                    Seg::Modify(1, dfn[x], max_num[x], z);
            }else{
                    scanf("%d", &x);
                    int Ans = Seg::Query(1, dfn[x], max_num[x]);
                    printf("%d
    ", Ans);
            }
    }
    
    int main(){
            scanf("%d%d%d%d", &N, &M, &R, &P);
            int a, b;
            for(reg int i = 1; i <= N; i ++) scanf("%d", &w[i]);
            Seg::Build(1, 1, N);
            for(reg int i = 1; i < N; i ++){
                    scanf("%d%d", &a, &b);
                    Add(a, b), Add(b, a);
            }
            DFS_1(R, R);            // second  'R' --> '0'
            DFS_2(R, R);            // second  'R' --> '0'
            while(M --) Work();
            return 0;
    }
    
    

    普通平衡树

    > 和 < 的区别
    5个数组
    对一个节点进行操作后进行Splay
    前驱后继的操作注意特判

    int S_pre(int x, short opt){  // 1: su  0:  pre
            find(x);
            if(opt == 1){	//特判
                    if(key[rot] > x) return rot;
            }else if(key[rot] < x) return rot;
            int t = ch[rot][opt]; opt ^= 1;
            while(ch[t][opt]) t = ch[t][opt];
            return t;
    }
    

    插入的时候必须Splay
    注意赋值关系

    //AC
    int Kth(int t, int x){
            while(1){
                    if(ch[t][0] && size[ch[t][0]] >= x) t = ch[t][0]; 
                    else if(size[ch[t][0]] + cnt[t] < x) x -= size[ch[t][0]] + cnt[t], t = ch[t][1];
                    else return t;
            }
    }
    //WA
    
    int Kth(int t, int x){
            while(1){
                    if(ch[t][0] && size[ch[t][0]] >= x) t = ch[t][0]; 
                    else if(size[ch[t][0]] + cnt[t] < x)  t = ch[t][1], x -= size[ch[t][0]] + cnt[t];
                    else return t;
            }
    }
    
    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 100005;
    
    int num0, rot;
    int cnt[maxn], size[maxn];
    int par[maxn], ch[maxn][2], key[maxn];
    
    inline void Push_up(int x){ size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x]; }
    
    inline bool chk(int x){ return ch[par[x]][1] == x; }
    
    void rotate(int x){
            int y = par[x], z = par[y], d = chk(x), s = ch[x][d^1];
            ch[y][d] = s, par[s] = y;
            ch[z][chk(y)] = x, par[x] = z;
            ch[x][d^1] = y, par[y] = x;
            Push_up(y), Push_up(x);
    }
    
    void Splay(int x, int aim=0){
            while(par[x] != aim){
                    int y = par[x], z = par[y];
                    if(z != aim){
                            if(chk(x) == chk(y)) rotate(y);
                            else rotate(x);
                    }
                    rotate(x);
            }
            if(!aim) rot = x;
    }
    
    void Insert(int x){ //~~
            int t = rot, last = 0;
            while(t && key[t] != x){
                    last = t;
                    t = ch[t][key[t] < x];
            }
            if(t) cnt[t] ++;
            else{
                    key[t = ++ num0] = x;
                    if(last) ch[last][key[last] < x] = num0;
                    ch[num0][0] = ch[num0][1] = 0, size[num0] = 1;
                    par[num0] = last;
                    cnt[num0] = 1;
            }
            Splay(t);
    }
    
    void find(int x){
            if(!rot) return ;
            int t = rot;
            while(ch[t][key[t] < x] && key[t] != x) t = ch[t][key[t] < x];
            Splay(t);
    }
    
    int S_pre(int x, short opt){  // 1: su  0:  pre
            find(x);
            
            if(opt == 1){
                    if(key[rot] > x) return rot;
            }else if(key[rot] < x) return rot;
            
            int t = ch[rot][opt]; opt ^= 1;
            while(ch[t][opt]) t = ch[t][opt];
            return t;
    }
    
    void Remove(int x){
            int su = S_pre(x, 1), pre = S_pre(x, 0);
            Splay(pre), Splay(su, pre);
            int t = ch[su][0];
            if(cnt[t] == 1) ch[su][0] = 0;
            else cnt[t] --, Splay(t);   //~~
    }
    
    inline void Ask_1(int x){
            find(x);
            printf("%d
    ", size[ch[rot][0]]);
    }
    
    int Kth(int t, int x){
            while(1){
                    if(ch[t][0] && size[ch[t][0]] >= x) t = ch[t][0]; 
                    else if(size[ch[t][0]] + cnt[t] < x) x -= size[ch[t][0]] + cnt[t], t = ch[t][1];
                    else return t;
            }
    }
    
    inline void Ask_2(int x){
    //        printf("fuck: %d size: %d cnt %d
    ",rot, size[ch[rot][0]], cnt[rot]);  
            int t = Kth(rot, x);
            printf("%d
    ", key[t]);
    }
    
    void Work(){
            int opt, x;
            scanf("%d%d", &opt, &x);
            if(opt == 1) Insert(x);
            else if(opt == 2) Remove(x);
            else if(opt == 3) Ask_1(x);
            else if(opt == 4) Ask_2(x+1);
            else if(opt == 5) printf("%d
    ", key[S_pre(x, 0)]);
            else printf("%d
    ", key[S_pre(x, 1)]);
    }
    
    int main(){
            int N;
            scanf("%d", &N);
            Insert(0xcfcfcfcf), Insert(0x3f3f3f3f);
            for(reg int i = 1; i <= N; i ++) Work();
            return 0;
    }
    

    最大流

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 100005;
    const int inf = 0x7f7f7f7f;
    
    int N, M, S, T, num0;
    int head[maxn], cur[maxn], dep[maxn];
    
    struct Edge{
            int nxt, to, dis, flow;
    } edge[maxn<<1];
    
    void Add(int from, int to, int Dis){
            edge[num0] = (Edge){ head[from], to, Dis, 0 };
            head[from] = num0 ++;
    }
    
    bool BFS(){
            memset(dep, -1, sizeof dep);
            for(reg int i = 0; i <= N; i ++) cur[i] = head[i];
            dep[S] = 1;
            std::queue <int> Q;
            Q.push(S);
            while(!Q.empty()){
                    int t = Q.front(); Q.pop();
                    for(reg int i = head[t]; ~i; i = edge[i].nxt){
                            int to = edge[i].to;
                            if(dep[to] == -1 && edge[i].dis > edge[i].flow){
                                    dep[to] = dep[t] + 1;
                                    Q.push(to);
                            }
                    }
            }
            return dep[T] != -1;
    }
    
    int DFS(int k, int W){
            if(k == T) return W;
            for(reg int &i = cur[k]; ~i; i = edge[i].nxt){
                    int to = edge[i].to;
                    if(dep[to] == dep[k] + 1 && edge[i].dis > edge[i].flow){
                            int tmp = DFS(to, std::min(W, edge[i].dis - edge[i].flow));
                            if(tmp){
                                    edge[i].flow += tmp;
                                    edge[i^1].flow -= tmp;
                                    return tmp;
                            }
                    }
            }
            return 0;
    }
    
    int Dinic(){
            int Ans = 0;
            while(BFS()){
                    while(int res = DFS(S, inf)) Ans += res;
            }
            return Ans;
    }
    
    int main(){
            scanf("%d%d%d%d", &N, &M, &S, &T);
            int x, y, z;
            memset(head, -1, sizeof head);
            for(reg int i = 1; i <= M; i ++){
                    scanf("%d%d%d", &x, &y, &z);
                    Add(x, y, z), Add(y, x, 0);
            }
            printf("%d
    ", Dinic());
            return 0;
    }
    /*
    memset(head, -1, sizeof head)
    
    void Add(int from, int to, int Dis){
            edge[num0] = (Edge){ head[from], to, Dis, 0 };
            head[from] = num0 ++;
    }
    
    */
    

    最小费用最大流

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 50005;
    
    int N, M, S, T, num0;
    int head[maxn];
    std::bitset <5005> Used;
    int Dis[5005], Flow[5005], Pre[5005], Pre_1[5005];
    
    struct Edge{
            int nxt, to, dis, flow, cost;
    } edge[maxn << 1];
    
    void Add(int from, int to, int dis, int cost){
            edge[num0] = (Edge){ head[from], to, dis, 0, cost };
            head[from] = num0 ++;
    }
    
    int Spfa(){
            memset(Dis, 0x3f, sizeof Dis);
            memset(Flow, 0x3f, sizeof Flow);
            Used.reset();
            std::queue <int> Q;
            Q.push(S), Dis[S] = 0, Used.set(S, 1);
            while(!Q.empty()){
                    int t = Q.front(); Q.pop();
                    //printf("fuck %d
    ", t);
                    Used.set(t, 0);
                    for(reg int i = head[t]; ~i; i = edge[i].nxt){
                            int to = edge[i].to;
                            if(Dis[to] > Dis[t] + edge[i].cost && edge[i].dis > edge[i].flow){
                                    Dis[to] = Dis[t] + edge[i].cost;
                                    Pre[to] = t;
                                    Pre_1[to] = i;
                                    Flow[to] = std::min(Flow[t], edge[i].dis - edge[i].flow);
                                    if(!Used.test(to)){
                                            Used.set(to, 1); Q.push(to);
                                    }
                            }
                    }
            }
            return Flow[T];
    }
    
    int MFMS(){
            int Ans = 0, res = 0, Ans_2 = 0;
            while((res = Spfa()) != 0x3f3f3f3f){
                    Ans += res;
                    Ans_2 += Dis[T] * Flow[T];
                    int t = T;
                    while(t != S){
                            int tmp = Pre_1[t];
                            edge[tmp].flow += res;
                            edge[tmp^1].flow -= res;
                            t = Pre[t];
                    }
            }
            printf("%d ", Ans);
            return Ans_2;
    }
    
    int main(){
    //        freopen("test.in", "r", stdin);
            scanf("%d%d%d%d", &N, &M, &S, &T);
            memset(head, -1, sizeof head);
            for(reg int i = 1; i <= M; i ++){
                    int x, y, z, w;
                    scanf("%d%d%d%d", &x, &y, &z, &w);
                    Add(x, y, z, w), Add(y, x, 0, -w);
            }
            printf("%d
    ", MFMS());
            return 0;
    }
    /*
    Add(x, y, z, w), Add(y, x, 0, -w);
    
    if(Dis[to] > Dis[t] + edge[i].cost && edge[i].dis > edge[i].flow){
            
    */
    
  • 相关阅读:
    hdu 5224 Tom and paper 水题
    2015 UESTC 搜索专题N题 韩爷的梦 hash
    2015 UESTC 搜索专题M题 Palindromic String 马拉车算法
    2015 UESTC 搜索专题K题 秋实大哥の恋爱物语 kmp
    2015 UESTC 搜索专题J题 全都是秋实大哥 kmp
    2015 UESTC 搜索专题F题 Eight Puzzle 爆搜
    2015 UESTC 搜索专题E题 吴队长征婚 爆搜
    2015 UESTC 搜索专题D题 基爷的中位数 二分
    2015 UESTC 搜索专题C题 基爷与加法等式 爆搜DFS
    2015 UESTC 搜索专题B题 邱老师降临小行星 记忆化搜索
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822646.html
Copyright © 2011-2022 走看看