zoukankan      html  css  js  c++  java
  • 板子2

      线段树(单点更新)

    /*  gyt
           Live up to every day            */
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 500002;
    const ll maxm = 1e7;
    const ll base = 2333;
    const int INF = 1<<30;
    const db eps = 1e-8;
    const ll mod = 1e9+13;
    struct nodee{
        int left, right, mid, num;
    }node[maxn];
    int ca=1;
    
    void build(int left, int right, int n) {
        node[n].left=left;
        node[n].right=right;
        node[n].mid=(left+right)/2;
        node[n].num=0;
        if (left+1==right)  return;
        build(left, (left+right)/2, 2*n);
        build((left+right)/2, right, 2*n+1);
    }
    void updata(int pos, int value, int n) {
        node[n].num+=value;
        if (node[n].left+1==node[n].right)
            return;
        if (pos<node[n].mid)
            updata(pos, value, 2*n);
        else
            updata(pos, value, 2*n+1);
    }
    int query(int left, int right, int n) {
        if (node[n].left==left && node[n].right==right) {
            return node[n].num;
        }
        if (left<node[n].mid) {
            if(right <= node[n].mid ){
                return query(left,right,2*n);
            }
            else{
                return query(left,node[n].mid,2*n) + query(node[n].mid,right,2*n + 1);
            }
        }
        else
            return query(left,right,2*n+1);
    }
    void solve() {
        int n;  scanf("%d", &n);
        build(1, n+1, 1);
        for (int i=1; i<=n; i++) {
            int x;  scanf("%d", &x);
            updata(i, x, 1);
        }
        char c[10];
        printf("Case %d:
    ", ca++);
        while(1) {
            scanf("%s", c);
            if (strcmp(c, "End")==0)  break;
            int x, y;  scanf("%d%d", &x, &y);
            if (strcmp(c, "Query")==0) {
                int ans=query(x, y+1, 1);
                printf("%d
    ", ans);
            }
             else if(strcmp(c,"Add") == 0){
                updata(x, y, 1);
            }
            else if(strcmp(c,"Sub") == 0){
                updata(x, -y, 1);
            }
        }
    }
    int main() {
        int t = 1;
       // freopen("in.txt","r",stdin);
      //  freopen("gcd.out","w",stdout);
        scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }

       dfs序+线段树

        将dfs序作为建树的标准

    /*  gyt
           Live up to every day            */
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    #define LL(x) (x<<1)
    #define RR(x) (x<<1|1)
    const int maxn = 100000+5;
    const ll maxm = 1e7;
    const ll base = 2333;
    const ll inf = 1e17;
    const db eps = 1e-8;
    const ll mod = 1e9+13;
    int a[maxn], n, m, cnt, head[maxn];
    int in[maxn], out[maxn], xx, idx[maxn];
    ll dis[maxn];  int ca=1;
    struct Edge{
        int v, next;
    }e[maxn*2];
    struct TREE{
        int l, r;  ll val, maxx, lazy;
        void fun(ll tmp) {
            lazy+=tmp;
            val+=(r-l+1)*tmp;
            maxx+=tmp;
        }
    }tree[maxn*4];
    
    void init() {
        xx=cnt=0;
        memset(head, -1, sizeof(head));
    }
    void add(int u, int v) {
        e[cnt].v=v, e[cnt].next=head[u];
        head[u]=cnt++;
    }
    void dfs(int u, int fa) {
        in[u]=++xx;  idx[xx]=u;
        for (int i=head[u]; ~i; i=e[i].next) {
            int v=e[i].v;
            if (v==fa)  continue;
            dis[v]=dis[u]+a[v];
            dfs(v, u);
        }
        out[u]=xx;
    }
    void pushup(int id) {
        tree[id].val=tree[id*2].val+tree[id*2+1].val;
        tree[id].maxx=max(tree[id*2].maxx, tree[id*2+1].maxx);
    }
    void pushdown(int id) {
        if (tree[id].lazy) {
            tree[id*2].fun(tree[id].lazy);
            tree[id*2+1].fun(tree[id].lazy);
            tree[id].lazy=0;
        }
    }
    void build(int id, int l, int r) {
        tree[id].l=l, tree[id].r=r, tree[id].lazy=0;
        if (l==r) {
            tree[id].val=tree[id].maxx=dis[idx[l]];
        }
        else {
            int mid=(l+r)/2;
            build(id*2, l, mid);
            build(id*2+1, mid+1, r);
            pushup(id);
        }
    }
    void updata(int id, int st, int ed, int val) {
        int l=tree[id].l, r=tree[id].r;
        if (st<=l&&r<=ed)  tree[id].fun(val);
        else {
            pushdown(id);
            int mid=(l+r)/2;
            if (st<=mid)  updata(id*2, st, ed, val);
            if (ed>mid)  updata(id*2+1, st, ed, val);
            pushup(id);
        }
    }
    ll quary(int id, int st, int ed) {
        int l=tree[id].l, r=tree[id].r;
        if (st<=l&&r<=ed)  return tree[id].maxx;
        else {
            pushdown(id);
            int mid=(l+r)/2;
            ll sum1=-inf, sum2=-inf;
            if (st<=mid)  sum1=quary(id*2, st, ed);
            if (ed>mid)  sum2=quary(id*2+1, st, ed);
            pushup(id);
            return max(sum1, sum2);
        }
    }
    void solve() {
        scanf("%d%d", &n, &m);
        init();
        for (int i=0; i<n-1; i++) {
            int u, v;  scanf("%d%d", &u, &v);
            add(u, v);  add(v, u);
        }
        for (int i=0; i<n; i++)  scanf("%d", a+i);
        dis[0]=a[0];
        dfs(0, -1);
        build(1, 1, n);
        printf("Case #%d:
    ", ca++);
        for (int i=0; i<m; i++) {
            int op, x;  scanf("%d%d", &op, &x);
            if (!op) {
                int y;  scanf("%d", &y);
                updata(1, in[x], out[x], y-a[x]);
                a[x]=y;
            }
            else {
                printf("%I64d
    ", quary(1, in[x], out[x]));
            }
        }
    }
    int main() {
        int t = 1;
        //freopen("in.txt","r",stdin);
      //  freopen("gcd.out","w",stdout);
        scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }
  • 相关阅读:
    BZOJ.3990.[SDOI2015]排序(DFS)
    BZOJ.1040.[ZJOI2008]骑士(树形DP)
    BZOJ.2246.[SDOI2011]迷宫探险(DP 记忆化搜索 概率)
    BZOJ.3209.花神的数论题(数位DP)
    UVA.1640.The Counting Problem / BZOJ.1833.[ZJOI2010]数字计数(数位DP)
    HDU.3652.B-number(数位DP)
    BZOJ.4514.[SDOI2016]数字配对(费用流SPFA 二分图)
    BZOJ.4832.[Lydsy1704月赛]抵制克苏恩(期望DP)
    BZOJ.1025.[SCOI2009]游戏(背包DP)
    BZOJ.3257.树的难题(树形DP)
  • 原文地址:https://www.cnblogs.com/gggyt/p/7249559.html
Copyright © 2011-2022 走看看