zoukankan      html  css  js  c++  java
  • Kuangbin 带你飞-线段树专题 题解

    HDU 1166 敌兵布阵

    单调更新区间查询和

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 50010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        int sum;
    }tree[MAXN * 4];
    int src[MAXN];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        if (l == r)
        {
            tree[id].sum = src[l];
            return;
        }
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
        tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;
    }
    
    void update(int id,int pos,int val)
    {
        if (tree[id].l == pos && tree[id].r == pos)
        {
            tree[id].sum += val;
            return;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (pos <= mid) update(id * 2,pos,val);
        else update(id * 2 + 1,pos,val);
        tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;
    }
    
    int query(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].sum;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return query(id * 2 + 1,l,r);
        else if (r <= mid) return query(id * 2,l,r);
        else
        {
            return query(id * 2 ,l,mid) + query(id * 2 + 1,mid + 1,r);
        }
    }
    
    int main()
    {
        int T,kase = 1;
        scanf("%d",&T);
        while (T--)
        {
            int N;
            scanf("%d",&N);
            for (int i = 1 ; i <= N ; i++) scanf("%d",&src[i]);
            build(1,1,N);
            printf("Case %d:
    ",kase++);
            char op[10];
            while(scanf("%s",op) != EOF)
            {
                if (op[0] == 'E') break;
                if (op[0] == 'Q')
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    printf("%d
    ",query(1,l,r));
                }
                if (op[0] == 'A')
                {
                    int x,val;
                    scanf("%d%d",&x,&val);
                    update(1,x,val);
                }
                if(op[0] == 'S')
                {
                    int x,val;
                    scanf("%d%d",&x,&val);
                    update(1,x,-val);
                }
            }
        }
        return 0;
    }
    View Code

    HDU 1754 I Hate It

    单点更新区间查询最值

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 200010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        int val;
    }tree[MAXN * 4];
    int src[MAXN];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        if (l == r)
        {
            tree[id].val = src[l];
            return;
        }
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
        tree[id].val = max(tree[id * 2].val,tree[id * 2 + 1].val);
    }
    
    void update(int id,int pos,int val)
    {
        if (tree[id].l == pos && tree[id].r == pos)
        {
            tree[id].val = val;
            return;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (pos <= mid) update(id * 2,pos,val);
        else update(id * 2 + 1,pos,val);
        tree[id].val = max(tree[id * 2].val,tree[id * 2 + 1].val);
    }
    
    int query(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].val;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return query(id * 2 + 1,l,r);
        else if (r <= mid) return query(id * 2,l,r);
        else
        {
            return max(query(id * 2,l,mid) ,query(id * 2 + 1,mid + 1,r));
        }
    }
    
    int main()
    {
        int N,Q;
        while (scanf("%d%d",&N,&Q) != EOF)
        {
            for (int i = 1 ; i <= N; i++) scanf("%d",&src[i]);
            build(1,1,N);
            while (Q--)
            {
                char op[5];
                scanf("%s",op);
                if (op[0] == 'Q')
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    printf("%d
    ",query(1,l,r));
                }
                else
                {
                    int x,val;
                    scanf("%d%d",&x,&val);
                    update(1,x,val);
                }
            }
        }
        return 0;
    }
    View Code

    POJ 3468 A Simple Problem with Integers

    区间更新区间求和。

    这里就要涉及到懒操作。注意的是lazy被更新的区间一定是当前的区间和已经更新完

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 100010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        LL lazy,sum;
    }tree[MAXN * 4];
    LL src[MAXN];
    
    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].sum = src[l];
            return;
        }
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid +1,r);
        tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;
    }
    
    void push_down(int id)
    {
        if (tree[id].lazy == 0) return;
        tree[id * 2].sum += (tree[id * 2].r - tree[id * 2].l + 1) * tree[id].lazy;
        tree[id * 2].lazy += tree[id].lazy;
        tree[id * 2 + 1].sum += (tree[id * 2 + 1].r - tree[id * 2 + 1].l + 1) * tree[id].lazy;
        tree[id * 2 + 1].lazy += tree[id].lazy;
        tree[id].lazy = 0;
    }
    
    
    void update(int id,int l,int r,LL val)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            tree[id].lazy += val;
            tree[id].sum += val * (r - l + 1);
            return;
        }
        push_down(id);
        int mid = (tree[id].r + tree[id].l) / 2;
        if (l > mid) update(id * 2 + 1,l,r,val);
        else if (r <= mid) update(id * 2 ,l,r,val);
        else
        {
            update(id * 2,l,mid,val);
            update(id * 2 + 1,mid + 1,r,val);
        }
        tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;
    }
    
    LL query(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].sum;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return query(id * 2 + 1,l,r);
        else if (r <= mid) return query(id * 2,l,r);
        else
        {
            return query(id * 2,l,mid) + query(id * 2 + 1,mid + 1,r);
        }
    }
    
    int main()
    {
        int N,Q;
        while (scanf("%d%d",&N,&Q) != EOF)
        {
            for (int i = 1 ; i <= N ; i++) scanf("%I64d",&src[i]);
            build(1,1,N);
            char op[10];
            while (Q--)
            {
                scanf("%s",op);
                if (op[0] == 'Q')
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    printf("%I64d
    ",query(1,l,r));
                }
                else
                {
                    int l,r;
                    LL val;
                    scanf("%d%d%I64d",&l,&r,&val);
                    update(1,l,r,val);
                }
            }
        }
        return 0;
    }
    View Code

    POJ 2528 Mayor's posters

    区间更新为一个值。然后统计有哪些数出现过

    注意需要离散化,且不能随便离散化。

    线段树是点操作。这里对长度为1的段进行操作。也就是将一个长度为1的段视作一个点,举个例子

    区间为 1-10,1--4,5 -- 10

    区间为 1--10,1--4,6-10;

    一般的离散化是变成了这样 1离散为1,4离散为2,5离散为3,10离散为4

    区间都变成了1-4,1--2,3 -- 4;

    显然上面2中答案是不一样的。随便离散是WA的。第一个答案是2,第二个答案是3

    那么如何改,方案是如果两个相邻的点差值大于1,那么中间就插入一个点。

    那么按照这种离散上面变成了有6个点1,3,4,5,9,10,离散成了1-6,1-3,4-6 答案为2

    和第二组问题 变成这样几个点1 3 4 5 6 9 10 离散成了 1--7,1--3,5--7答案为3

    代码

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 10010;
    map<int,int>mp,res;
    struct point
    {
        int l,r;
        int idx;
    }src[MAXN];
    struct node
    {
        int l,r;
        int val;
        bool flag;
    }tree[MAXN * 16];
    int ori[MAXN * 2],newdata[MAXN * 4];
    
    void build(int id,int l,int r)
    {
        tree[id].l = newdata[l];
        tree[id].r = newdata[r];
        tree[id].val = -1;
        tree[id].flag = false;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    void push_down(int id)
    {
        if (tree[id].flag)
        {
            tree[id * 2].flag = tree[id * 2 + 1].flag = true;
            tree[id * 2].val = tree[id * 2 + 1].val = tree[id].val;
            tree[id].flag = false;
        }
    }
    
    void update(int id,int l,int r,int val)
    {
        if (r < tree[id].l || l > tree[id].r) return;
        if (tree[id].l >= l && tree[id].r <= r)
        {
            tree[id].val = val;
            tree[id].flag = true;
            return;
        }
        push_down(id);
        /*int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) update(id * 2 + 1,l,r,val);
        else if (r <= mid) update(id * 2,l,r,val);
        else
        {
            update(id * 2 ,l,mid,val);
            update(id * 2 + 1,mid + 1,r,val);
        }*/
        update(id * 2,l,r,val);
        update(id * 2 + 1,l,r,val);
    }
    
    void query(int id,int l,int r,int &ret)
    {
        if (tree[id].l == tree[id].r)
        {
            if (mp[tree[id].val] == 0 && tree[id].val != -1)
            {
                ret++;
               // printf("%d
    ",tree[id].val);
                mp[tree[id].val] = 1;
            }
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        query(id * 2,l,mid,ret);
        query(id * 2 + 1,mid + 1,r,ret);
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
            mp.clear();
            res.clear();
            int N;
            scanf("%d",&N);
            int cas = 0;
            for (int i = 1;  i <= N ; i++)
            {
                scanf("%d%d",&src[i].l,&src[i].r);
                src[i].idx = i;
                ori[++cas] = src[i].l;
                ori[++cas] = src[i].r;
            }
            sort(ori + 1,ori + 1 + cas);
            int leap = 0;
            ori[0] = -1;
            for (int i = 1; i <= cas ; i++)
            {
                if (ori[i] != ori[i - 1])
                    ori[++leap] = ori[i];
            }
            cas = 0;
            newdata[++cas] = ori[1];
            for (int i = 2 ; i <= leap ; i++)
            {
                if (ori[i] > ori[i - 1] + 1)
                {
                    newdata[++cas] = ori[i] - 1;
                    newdata[++cas] = ori[i];
                }
                else
                {
                    newdata[++cas] = ori[i];
                }
            }
           // printf("%d
    ",cas);
            //for (int i = 1 ; i <= cas ; i++)
            //   printf("%d ",newdata[i]); putchar('
    ');
            build(1,1,cas);
            for (int i = 1 ; i <= N ; i++)
            {
                update(1,src[i].l,src[i].r,src[i].idx);
            }
            int ret = 0;
            query(1,1,cas,ret);
            printf("%d
    ",ret);
        }
        return 0;
    }
    View Code

    hdu 1698 Just a Hook

    记得题意是如果一个区间值全部相等,那么权就是这个区间的长度乘以这个值,最开始全都是1

    用一个sta记录这个区间是不是所值都相等然后做

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 100010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        bool sta;
        int val;
        bool flag;
    }tree[MAXN * 4];
    int L;
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].val = 1;
        tree[id].flag = false;
        tree[id].sta = true;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    void push_down(int id)
    {
        if (tree[id].flag)
        {
            tree[id * 2].val = tree[id * 2 + 1].val = tree[id].val;
            tree[id * 2].flag = true;
            tree[id * 2 + 1].flag = true;
            tree[id].flag = false;
            tree[id].sta = true;
            tree[id * 2].sta = true;
            tree[id * 2 + 1].sta = true;
        }
    }
    
    
    void push_up(int id)
    {
        if (tree[id * 2].sta == true && tree[id * 2 + 1].sta == true)
        {
            if (tree[id * 2].val == tree[id * 2 + 1].val)
            {
                tree[id].val = tree[id * 2 + 1].val;
                tree[id].sta = true;
            }
            else tree[id].sta = false;
        }
        else tree[id].sta = false;
    }
    
    void update(int id,int l,int r,int val)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            tree[id].flag = true;
            tree[id].val = val;
            tree[id].sta = true;
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) update(id * 2 + 1,l,r,val);
        else if (r <= mid) update(id * 2,l,r,val);
        else
        {
            update(id * 2,l,mid,val);
            update(id * 2 + 1,mid + 1,r,val);
        }
        push_up(id);
    }
    
    int query(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            if (tree[id].sta == true)
            {
               // printf("%d %d %d
    ",tree[id].l,tree[id].r,tree[id].val);
                return tree[id].val * (tree[id].r - tree[id].l + 1);
            }
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return query(id * 2 + 1,l,r);
        else if (r <= mid) return query(id * 2,l,r);
        else
        {
            return query(id * 2,l,mid) + query(id * 2 + 1,mid + 1,r);
        }
    }
    
    int main()
    {
        int T,kase = 1;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&L);
            build(1,1,L);
            int Q;
            scanf("%d",&Q);
            while (Q--)
            {
                int l,r,val;
                scanf("%d%d%d",&l,&r,&val);
                update(1,l,r,val);
                //printf("%d %d %d
    ",l,r,val);
            }
            printf("Case %d: The total value of the hook is %d.
    ",kase++,query(1,1,L));
        }
        return 0;
    }
    View Code

    ZOJ 1610 Count the Colors

    只有一次查询。可以直接暴力出来修改后最后每个点的颜色。然后扫一遍

    我第一次的做法不知道为何就是老WA。求好心人告知。

    下面是参照别人A的代码

    结构体的COL表示染了什么颜色

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 8110;
    struct node
    {
        int l,r,col;
    }tree[MAXN * 4];
    int cnt[MAXN],col[MAXN],N;
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].col = -1;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    
    void push_down(int id)
    {
        if (tree[id].col != -1)
        {
            tree[id * 2].col = tree[id * 2 + 1].col = tree[id].col;
            tree[id].col = -1;
        }
    }
    
    void update(int id,int l,int r,int val)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            tree[id].col = val;
            //printf("%d %d %d
    ",tree[id].l,tree[id].r,tree[id].col);
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) update(id * 2 + 1,l,r,val);
        else if (r <= mid) update(id * 2,l,r,val);
        else
        {
            update(id * 2,l,mid,val);
            update(id * 2 + 1,mid + 1,r,val);
        }
    }
    
    void query(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            //printf("%d
    ",tree[id].col);
            if (tree[id].col != -1)
            {
                //printf("%d
    ",tree[id].col);
                for (int i = tree[id].l ; i <= tree[id].r ; i++)
                    col[i] = tree[id].col;
                return;
            }
        }
        push_down(id);
        if (l == r) return;
        int mid = (tree[id].l + tree[id].r ) / 2;
        if (l > mid) query(id * 2 + 1,l,r);
        else if (r <= mid) query(id * 2,l,r);
        else
        {
            query(id * 2,l,mid);
            query(id * 2 + 1,mid + 1,r);
        }
    }
    
    int main()
    {
        while (scanf("%d",&N) != EOF)
        {
            memset(cnt,0,sizeof(cnt));
            build(1,1,8000);
            for (int i = 1 ; i <= N ; i++)
            {
                int l,r,val;
                scanf("%d%d%d",&l,&r,&val);
                update(1,l + 1,r,val);
            }
            memset(col,-1,sizeof(col));
            query(1,1,8000);
            int pre = -1;
            for (int i = 0 ; i <= 8000 ; i++)
            {
                if (col[i] == -1)
                {
                    pre = -1;
                    continue;
                }
                if (pre != col[i])
                {
                    cnt[col[i]]++;
                    pre = col[i];
                }
            }
            for (int i = 0 ; i <= 8000 ; i++)
            {
                if (cnt[i]) printf("%d %d
    ",i,cnt[i]);
            }
            puts("");
        }
        return 0;
    }
    View Code

    下面是我自己WA的代码在查询中就更新出答案不知道那里有问题

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 8110;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        bool flag,sta;
        int val;
    }tree[MAXN * 4];
    int N;
    int cnt[MAXN];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].val = -1;
        tree[id].flag = false;
        tree[id].sta = true;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    void push_down(int id)
    {
        if (tree[id].flag)
        {
            tree[id * 2].val = tree[id * 2 + 1].val = tree[id].val;
            tree[id * 2].flag = true;
            tree[id * 2 + 1].flag = true;
            tree[id].flag = false;
            tree[id].sta = true;
            tree[id * 2].sta = true;
            tree[id * 2 + 1].sta = true;
        }
    }
    
    
    void push_up(int id)
    {
        if (tree[id * 2].sta == true && tree[id * 2 + 1].sta == true)
        {
            if (tree[id * 2].val == tree[id * 2 + 1].val)
            {
                tree[id].val = tree[id * 2 + 1].val;
                tree[id].sta = true;
            }
            else tree[id].sta = false;
        }
        else tree[id].sta = false;
    }
    
    void update(int id,int l,int r,int val)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            tree[id].flag = true;
            tree[id].val = val;
            tree[id].sta = true;
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) update(id * 2 + 1,l,r,val);
        else if (r <= mid) update(id * 2,l,r,val);
        else
        {
            update(id * 2,l,mid,val);
            update(id * 2 + 1,mid + 1,r,val);
        }
        push_up(id);
    }
    
    void query(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            if (tree[id].sta == true)
            {
                if (tree[id].val != -1)
                {
                    cnt[tree[id].val]++;
                  //a  printf("%d
    ",tree[id].val);
                }
                return;
            }
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) query(id * 2 + 1,l,r);
        else if (r <= mid) query(id * 2 ,l,r);
        else
        {
            query(id * 2,l,mid);
            query(id * 2 + 1,mid + 1,r);
        }
    }
    
    int main()
    {
        //freopen("sample.txt","r",stdin);
        while (scanf("%d",&N) != EOF)
        {
            build(1,1,8010);
            for (int i = 1 ; i <= N ; i++)
            {
                int l,r,val;
                scanf("%d%d%d",&l,&r,&val);
                if (l > r) swap(l,r);
                if (l == r) continue;
                update(1,l + 1,r,val);
            }
            memset(cnt,0,sizeof(cnt));
            query(1,1,8010);
            for (int i = 0 ; i <= 8010 ; i++)
            {
                if (cnt[i] == 0) continue;
                printf("%d %d
    ",i,cnt[i]);
            }
            puts("");
        }
        return 0;
    }
    View Code

    POJ 3264 Balanced Lineup

    查询区间最大最小值。

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 50010;
    struct node
    {
        int l,r,MIN,MAX;
    }tree[MAXN * 4];
    int src[MAXN],N;
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        if (l == r)
        {
            tree[id].MIN = tree[id].MAX = src[l];
            return;
        }
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
        tree[id].MIN = min(tree[id * 2].MIN,tree[id * 2 + 1].MIN);
        tree[id].MAX = max(tree[id * 2].MAX,tree[id * 2 + 1].MAX);
    }
    
    int querymax(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].MAX;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return querymax(id * 2 + 1,l,r);
        else if (r <= mid) return querymax(id * 2,l,r);
        else
        {
            return max(querymax(id * 2,l,mid),querymax(id * 2 + 1,mid + 1,r));
        }
    }
    
    int querymin(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].MIN;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return querymin(id * 2 + 1,l,r);
        else if (r <= mid) return querymin(id * 2,l,r);
        else
        {
            return min(querymin(id * 2,l,mid),querymin(id * 2 + 1,mid + 1,r));
        }
    }
    
    int main()
    {
        int Q;
        while (scanf("%d%d",&N,&Q) != EOF)
        {
            for (int i = 1 ; i <= N ; i++) scanf("%d",&src[i]);
            build(1,1,N);
            while (Q--)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                printf("%d
    ",querymax(1,l,r) - querymin(1,l,r));
            }
        }
        return 0;
    }
    View Code

    HDU 4027 Can you answer these queries?

    每次操作把区间内所有值开跟好向下取整,最大的数最多开7次根到1,所以直接做区间长度等于区间和直接结束

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 100010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        LL sum;
        bool flag;
    }tree[MAXN * 4];
    LL src[MAXN];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        if (l == r)
        {
            tree[id].sum = src[l];
            return;
        }
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
        tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;
    }
    
    void push_down(int id)
    {
        if (tree[id].l == tree[id].r)
        {
            tree[id].sum = (LL)sqrt(1.0 * tree[id].sum);
            return;
        }
        push_down(id * 2);
        push_down(id * 2 + 1);
        tree[id].sum = tree[id * 2 + 1].sum + tree[id * 2].sum;
    }
    
    void update(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            if (tree[id].sum == (LL)(tree[id].r - tree[id].l + 1))
                return;
            push_down(id);
            return;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) update(id * 2 + 1,l,r);
        else if (r <= mid) update(id * 2,l,r);
        else
        {
            update(id * 2,l,mid);
            update(id * 2 + 1,mid + 1,r);
        }
        tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;
    }
    
    LL query(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].sum;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return query(id * 2 + 1,l,r);
        else if (r <= mid) return query(id * 2,l,r);
        else
        {
            return query(id * 2,l,mid) + query(id * 2 + 1,mid + 1,r);
        }
    }
    
    int main()
    {
        int N,M,kase = 1;
        while (scanf("%d",&N) != EOF)
        {
            for (int i = 1 ; i <= N ; i++) scanf("%I64d",&src[i]);
            scanf("%d",&M);
            build(1,1,N);
            printf("Case #%d:
    ",kase++);
            while (M--)
            {
                int op;
                scanf("%d",&op);
                if (op == 0)
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    if (l > r) swap(l,r);
                    update(1,l,r);
                }
                else
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    if (l > r) swap(l,r);
                    printf("%I64d
    ",query(1,l,r));
                }
            }
            putchar('
    ');
        }
        return 0;
    }
    View Code

    HDU 1540 Tunnel Warfare

    维护左连续长,右连续长,最大连续长度

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 50010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        int leftlen,rightlen,maxlen;
    }tree[MAXN * 4];
    stack<int>s;
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].leftlen = tree[id].rightlen = tree[id].maxlen = r - l + 1;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    
    void push_up(int id)
    {
        //leftlen;
        if (tree[id * 2].leftlen == tree[id * 2].r - tree[id * 2].l + 1)
        {
            tree[id].leftlen = tree[id * 2].r - tree[id * 2].l + 1 + tree[id * 2 + 1].leftlen;
        }
        else tree[id].leftlen = tree[id * 2].leftlen;
        //right len
        if (tree[id * 2 + 1].rightlen == tree[id * 2 + 1].r - tree[id * 2 + 1].l + 1)
        {
            tree[id].rightlen = tree[id * 2 + 1].r - tree[id * 2 + 1].l + 1 + tree[id * 2].rightlen;
        }
        else tree[id].rightlen = tree[id * 2 + 1].rightlen;
        tree[id].maxlen = max(tree[id * 2].maxlen,tree[id * 2 + 1].maxlen);
        tree[id].maxlen = max(tree[id].maxlen,tree[id * 2].rightlen + tree[id * 2 + 1].leftlen);
    }
    
    void update(int id,int pos,bool flag)
    {
        if (tree[id].l == tree[id].r)
        {
            if (flag)
                tree[id].maxlen = tree[id].leftlen = tree[id].rightlen = 0;
            else
                tree[id].maxlen = tree[id].leftlen = tree[id].rightlen = 1;
            return;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (pos > mid) update(id * 2 + 1,pos,flag);
        if (pos <= mid) update(id * 2,pos,flag);
        push_up(id);
    }
    
    int query(int id,int pos)
    {
        if (tree[id].l == tree[id].r ||
                tree[id].maxlen == tree[id].r - tree[id].l + 1)
        {
            return tree[id].maxlen;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (pos <= mid)//左半段
        {
            int tmppos = tree[id * 2].r - tree[id * 2].rightlen + 1;
            if (pos >= tmppos) return tree[id * 2].rightlen + tree[id * 2 + 1].leftlen;
            else return query(id * 2,pos);
        }
        else
        {
            int tmppos = tree[id * 2 + 1].l + tree[id * 2 + 1].leftlen - 1;
            if (pos <= tmppos) return tree[id * 2 + 1].leftlen + tree[id * 2].rightlen;
            else return query(id * 2 + 1,pos);
        }
    }
    
    int main()
    {
        //freopen("sample.txt","r",stdin);
        int N,Q;
        while (scanf("%d%d",&N,&Q) != EOF)
        {
            build(1,1,N);
            while (!s.empty()) s.pop();
            while (Q--)
            {
                char op[5];
                scanf("%s",op);
                if (op[0] == 'D')
                {
                    int pos;
                    scanf("%d",&pos);
                    s.push(pos);
                    update(1,pos,true);
                }
                if (op[0] == 'Q')
                {
                    int pos;
                    scanf("%d",&pos);
                    printf("%d
    ",query(1,pos));
                }
                if (op[0] == 'R')
                {
                    if (s.empty()) continue;
                    int x = s.top();
                    s.pop();
                    update(1,x,false);
                }
            }
        }
        return 0;
    }
    View Code

    HDU 3794 Assign the task

    其实就一个树形转线性

    别的随便做,代码里有排除爆炸手写的树形转线性存一下模版

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 50010;
    int L[MAXN],R[MAXN];
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        int val;
        bool flag;
    }tree[MAXN * 4];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].val = -1;
        tree[id].flag = false;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    void push_down(int id)
    {
        if (tree[id].flag)
        {
            tree[id * 2].flag = tree[id * 2 + 1].flag = true;
            tree[id * 2].val = tree[id * 2 + 1].val = tree[id].val;
            tree[id].flag = false;
        }
    }
    
    void update(int id,int l,int r,int val)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            tree[id].flag = true;
            tree[id].val = val;
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) update(id * 2 + 1,l,r,val);
        else if (r <= mid) update(id * 2,l,r,val);
        else
        {
            update(id * 2,l,mid,val);
            update(id * 2 + 1,mid + 1,r,val);
        }
    }
    
    int query(int id,int pos)
    {
        if (tree[id].l == pos && tree[id].r == pos)
        {
            return tree[id].val;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (pos > mid) return query(id * 2 + 1,pos);
        else return query(id * 2,pos);
    }
    
    /*
    int Stack[MAXN * 2],top;
    int deg[MAXN];
    int Index,seq[MAXN];
    bool vis[MAXN];
    queue<int>q[MAXN];
    
    void get_seq(int st)//这段先序遍历树形转线性我应该是不会的
    {
        int pos;
        int idx = 0;
        top = 1;
        Stack[top] = st;
        memset(vis,false,sizeof(vis));
        while (top)
        {
            pos = Stack[top];
            if (!vis[pos])
            {
                vis[pos] = true;
                seq[++idx] = pos;
                L[pos] = idx;
            }
            if (!q[pos].empty())
            {
                Stack[++top] = q[pos].front();
                q[pos].pop();
            }
            else
            {
                R[pos] = idx;
                top--;
            }
        }
    }*/
    vector<int>q[MAXN];
    int Index;
    int deg[MAXN];
    bool vis[MAXN];
    
    
    void get_seq(int u)
    {
        L[u] = ++Index;
        vis[u] = true;
        for (int i = 0 ; i < (int)q[u].size() ; i++)
        {
            int v = q[u][i];
            if (vis[v]) continue;
            get_seq(v);
        }
        R[u] = Index;
    }
    
    int main()
    {
        //freopen("sample.txt","r",stdin);
        int T,kase = 1;
        scanf("%d",&T);
        int N,Q;
        while(T--)
        {
            memset(deg,0,sizeof(deg));
            scanf("%d",&N);
            for (int i = 1 ; i <= N ; i++) q[i].clear();
            for (int i = 1 ; i < N ; i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                //q[v].push(u);
                q[v].push_back(u);
                deg[u]++;
            }
            build(1,1,N);
            int root = 1;
            for (int i = 1 ; i <= N ; i++)
            {
                if (deg[i] == 0)
                {
                    root = i;
                    break;
                }
            }
            Index = 0;
            memset(vis,false,sizeof(vis));
            //printf("%d
    ",root);
            get_seq(root);
            printf("Case #%d:
    ",kase++);
            //for (int i = 1 ; i <= N ; i++) printf("%d %d
    ",L[i],R[i]);
            scanf("%d",&Q);
            while (Q--)
            {
                char op[5];
                scanf("%s",op);
                if (op[0] == 'C')
                {
                    int x;
                    scanf("%d",&x);
                    printf("%d
    ",query(1,L[x]));
                }
                else
                {
                    int x,val;
                    scanf("%d%d",&x,&val);
                    //printf("%d %d
    ",L[x],R[x]);
                    update(1,L[x],R[x],val);
                }
            }
        }
        return 0;
    }
    View Code

    HDU 4578 Transformation

    这题很吊看这里 http://www.cnblogs.com/Commence/p/4871352.html

    HDU 4614 Vases and Flowers

    如果某个点可以插花,那么这个点值为1,由于他就是从左往右一直插花,实际上就是二分+区间和的问题。

    然后查询一个区间最左边的1和最右边的1

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 50010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        int sum,lazy,lft,rht;
    }tree[MAXN * 4];
    int N,Q;
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].sum = r - l + 1;
        tree[id].lft = l;
        tree[id].rht = r;
        tree[id].lazy = 0;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    void push_up(int id)
    {
        if (tree[id].l == tree[id].r) return;
        tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;
        if (tree[id * 2].lft != -1) tree[id].lft = tree[id * 2].lft;
        else tree[id].lft = tree[id * 2 + 1].lft;
        if (tree[id * 2 + 1].rht != -1) tree[id].rht = tree[id * 2 + 1].rht;
        else tree[id].rht = tree[id * 2].rht;
    }
    
    void push_down(int id)
    {
        if (tree[id].l == tree[id].r) return;
        if (tree[id].lazy == 1)
        {
            tree[id * 2].lft = tree[id * 2].l;
            tree[id * 2].rht = tree[id * 2].r;
            tree[id * 2].sum = tree[id * 2].r - tree[id * 2].l + 1;
            tree[id * 2].lazy = 1;
            tree[id * 2 + 1].lft = tree[id * 2 + 1].l;
            tree[id * 2 + 1].rht = tree[id * 2 + 1].r;
            tree[id * 2 + 1].sum = tree[id * 2 + 1].r - tree[id * 2 + 1].l + 1;
            tree[id * 2 + 1].lazy = 1;
        }
        if (tree[id].lazy == -1)
        {
            tree[id * 2].lft = -1;
            tree[id * 2].rht = -1;
            tree[id * 2].sum = 0;
            tree[id * 2].lazy = -1;
            tree[id * 2 + 1].lft = -1;
            tree[id * 2 + 1].rht = -1;
            tree[id * 2 + 1].sum = 0;
            tree[id * 2 + 1].lazy = -1;
        }
        tree[id].lazy = 0;
    }
    
    void update(int id,int l,int r,int val)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            if (val == 0)
            {
                if (tree[id].sum == 0) return;
                tree[id].sum = 0;
                tree[id].lft = -1;
                tree[id].rht = -1;
                tree[id].lazy = -1;
                return;
            }
            else if (val == 1)
            {
                if (tree[id].r - tree[id].l + 1 == tree[id].sum) return;
                tree[id].sum = tree[id].r - tree[id].l + 1;
                tree[id].lazy = 1;
                tree[id].lft = tree[id].l;
                tree[id].rht = tree[id].r;
                return;
            }
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) update(id * 2 + 1,l,r,val);
        else if (r <= mid) update(id * 2,l,r,val);
        else
        {
            update(id * 2,l,mid,val);
            update(id * 2 + 1,mid + 1,r,val);
        }
        push_up(id);
    }
    
    int getsum(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].sum;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return getsum(id * 2 + 1,l,r);
        else if (r <= mid) return getsum(id * 2,l,r);
        else
        {
            return getsum(id * 2,l,mid) + getsum(id * 2 + 1,mid + 1,r);
        }
    }
    
    int queryleft(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].lft;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return queryleft(id * 2 + 1,l,r);
        else if (r <= mid) return queryleft(id * 2,l,r);
        else
        {
            int ret;
            ret = queryleft(id * 2,l,mid);
            if (ret != -1) return ret;
            ret = queryleft(id * 2 + 1,mid + 1,r);
            return ret;
        }
    }
    
    int queryright(int id,int l,int r)
    {
        if (tree[id].l >= l && tree[id].r <= r)
        {
            return tree[id].rht;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) return queryright(id * 2 + 1,l,r);
        else if (r <= mid) return queryright(id * 2,l,r);
        else
        {
            int ret = queryright(id * 2 + 1,mid + 1,r);
            if (ret != -1) return ret;
            return queryright(id * 2,l,mid);
        }
    }
    
    int binseach(int A,int F)
    {
        int tmp = getsum(1,A,N);
        if (tmp == 0) return - 1;
        if (tmp < F) return N;
        int l = A,r = N;
        while (l < r)
        {
            int mid = (l + r) / 2;
            int val = getsum(1,A,mid);
            if (val >= F)
            {
                r = mid;
            }
            else l = mid + 1;
        }
        return l;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d%d",&N,&Q);
            build(1,1,N);
            while (Q--)
            {
                int op;
                scanf("%d",&op);
                if (op == 1)
                {
                    int A,F;
                    scanf("%d%d",&A,&F);
                    A++;
                    int tmp = binseach(A,F);
                    if (tmp == -1)
                    {
                        puts("Can not put any one.");
                        continue;
                    }
                    printf("%d %d
    ",queryleft(1,A,tmp) - 1,queryright(1,A,tmp) - 1);
                    update(1,A,tmp,0);
                }
                else
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    l++;
                    r++;
                    printf("%d
    ",r - l + 1 - getsum(1,l,r));
                    update(1,l,r,1);
                }
            }
            putchar('
    ');
        }
        return 0;
    }
    View Code

    HDU 4553 约会安排

    一个优先级问题,优先女神,然后吊斯

    女神的询问中先在吊死中找如果吊死中可以满足就同时更新吊死和女神的那个区间值详情看代码

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 100010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        int lmax,rmax,mmax;
        int lmax1,rmax1,mmax1;
    }tree[MAXN * 4];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].lmax = tree[id].rmax = tree[id].mmax = r - l + 1;
        tree[id].lmax1 = tree[id].rmax1 = tree[id].mmax1 = r - l + 1;
        if (l == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    void push_up(int id)
    {
        if (tree[id].r == tree[id].l) return;
        tree[id].lmax = tree[id * 2].lmax;
        if (tree[id * 2].lmax == tree[id * 2].r - tree[id * 2].l + 1)
                tree[id].lmax += tree[id * 2 + 1].lmax;
        tree[id].rmax = tree[id * 2 + 1].rmax;
        if (tree[id * 2 + 1].rmax == tree[id * 2 + 1].r - tree[id * 2 + 1].l + 1)
                tree[id].rmax += tree[id * 2].rmax;
        tree[id].mmax = max(tree[id * 2].mmax,tree[id * 2 + 1].mmax);
        tree[id].mmax = max(tree[id].mmax,tree[id * 2].rmax + tree[id * 2 + 1].lmax);
    
        tree[id].lmax1 = tree[id * 2].lmax1;
        if (tree[id * 2].lmax1 == tree[id * 2].r - tree[id * 2].l + 1)
                tree[id].lmax1 += tree[id * 2 + 1].lmax1;
        tree[id].rmax1 = tree[id * 2 + 1].rmax1;
        if (tree[id * 2 + 1].rmax1 == tree[id * 2 + 1].r - tree[id * 2 + 1].l + 1)
                tree[id].rmax1 += tree[id * 2].rmax1;
        tree[id].mmax1 = max(tree[id * 2].mmax1,tree[id * 2 + 1].mmax1);
        tree[id].mmax1 = max(tree[id].mmax1,tree[id * 2].rmax1 + tree[id * 2 + 1].lmax1);
    }
    
    void push_down(int id)
    {
        if (tree[id].l == tree[id].r) return;
        if (tree[id].mmax == 0)
        {
            tree[id * 2].lmax = tree[id * 2].rmax = tree[id * 2].mmax = 0;
            tree[id * 2 + 1].lmax = tree[id * 2 + 1].rmax = tree[id * 2 + 1].mmax = 0;
        }
        if (tree[id].mmax == tree[id].r - tree[id].l + 1)
        {
            tree[id * 2].lmax = tree[id * 2].rmax = tree[id * 2].mmax = tree[id * 2].r - tree[id * 2].l + 1;
            tree[id * 2 + 1].lmax = tree[id * 2 + 1].rmax = tree[id * 2 + 1].mmax = tree[id * 2 + 1].r - tree[id * 2 + 1].l + 1;
        }
        if (tree[id].mmax1 == 0)
        {
            tree[id * 2].lmax1 = tree[id * 2].rmax1 = tree[id * 2].mmax1 = 0;
            tree[id * 2 + 1].lmax1 = tree[id * 2 + 1].rmax1 = tree[id * 2 + 1].mmax1 = 0;
        }
        if (tree[id].mmax1 == tree[id].r - tree[id].l + 1)
        {
            tree[id * 2].lmax1 = tree[id * 2].rmax1 = tree[id * 2].mmax1 = tree[id * 2].r - tree[id * 2].l + 1;
            tree[id * 2 + 1].lmax1 = tree[id * 2 + 1].rmax1 = tree[id * 2 + 1].mmax1 = tree[id * 2 + 1].r - tree[id * 2 + 1].l + 1;
        }
    }
    
    int query(int id,int x)
    {
        if (tree[id].mmax < x) return 0;
        if (tree[id].lmax >= x) return tree[id].l;
        if (tree[id * 2].mmax >= x) return query(id * 2,x);
        if (tree[id * 2].rmax + tree[id * 2 + 1].lmax >= x)
                return tree[id * 2].r- tree[id * 2].rmax + 1;
        return query(id * 2 + 1,x);
    }
    
    int query1(int id,int x)
    {
        if (tree[id].mmax1 < x) return 0;
        if (tree[id].lmax1 >= x) return tree[id].l;
        if (tree[id * 2].mmax1 >= x) return query1(id * 2,x);
        if (tree[id * 2].rmax1 + tree[id * 2 + 1].lmax1 >= x)
                return tree[id * 2].r- tree[id * 2].rmax1 + 1;
        return query1(id * 2 + 1,x);
    }
    
    void update(int id,int l,int r)
    {
        if (tree[id].l == l && tree[id].r == r)
        {
            tree[id].mmax = tree[id].lmax = tree[id].rmax = tree[id].r - tree[id].l + 1;
            tree[id].mmax1 = tree[id].lmax1 = tree[id].rmax1 = tree[id].r - tree[id].l + 1;
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) update(id * 2 + 1,l,r);
        else if (r <= mid) update(id * 2 ,l,r);
        else
        {
            update(id * 2,l,mid);
            update(id * 2 + 1,mid + 1,r);
        }
        push_up(id);
    }
    
    void diors(int id,int l,int r)
    {
        if (tree[id].l == l && tree[id].r == r)
        {
            tree[id].mmax = tree[id].lmax = tree[id].rmax = 0;
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) diors(id * 2 + 1,l,r);
        else if (r <= mid) diors(id * 2,l,r);
        else
        {
            diors(id * 2,l,mid);
            diors(id * 2 + 1,mid + 1,r);
        }
        push_up(id);
    }
    
    void godness(int id,int l,int r)
    {
        if (tree[id].l == l && tree[id].r == r)
        {
            tree[id].mmax = tree[id].lmax = tree[id].rmax = 0;
            tree[id].mmax1 = tree[id].lmax1 = tree[id].rmax1 = 0;
            return;
        }
        push_down(id);
        int mid = (tree[id].l + tree[id].r) / 2;
        if (l > mid) godness(id * 2 + 1,l,r);
        else if (r <= mid) godness(id * 2 ,l,r);
        else
        {
            godness(id * 2,l,mid);
            godness(id * 2 + 1,mid + 1,r);
        }
        push_up(id);
    }
    
    int main()
    {
        //freopen("sample.txt","r",stdin);
        int T,kase = 1;
        scanf("%d",&T);
        while (T--)
        {
            printf("Case %d:
    ",kase++);
            int N,M;
            scanf("%d%d",&N,&M);
            build(1,1,N);
            while (M--)
            {
                char op[5];
                scanf("%s",op);
                if (op[0] == 'D')
                {
                    int x;
                    scanf("%d",&x);
                    int tmp = query(1,x);
                    if (tmp == 0) puts("fly with yourself");
                    else
                    {
                        diors(1,tmp,tmp + x - 1);
                        printf("%d,let's fly
    ",tmp);
                    }
                }
                else if (op[0] == 'N')
                {
                    int x;
                    scanf("%d",&x);
                    int tmp = query(1,x);
                    if (tmp != 0)
                    {
                        godness(1,tmp,tmp + x - 1);
                        printf("%d,don't put my gezi
    ",tmp);
                        continue;
                    }
                    tmp = query1(1,x);
                    if (tmp != 0)
                    {
                        godness(1,tmp,tmp + x - 1);
                        printf("%d,don't put my gezi
    ",tmp);
                        continue;
                    }
                    printf("wait for me
    ");
                }
                else
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    printf("I am the hope of chinese chengxuyuan!!
    ");
                    update(1,l,r);
                }
            }
        }
        return 0;
    }
    View Code

    POJ 1177 Picture

    线段树扫描线矩形周长并

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 10010;
    struct node
    {
        int l,r;
        int cnt;
        int lf,rf;
        int numseg;
        int c;
        bool lcover,rcover;
    }tree[MAXN * 4];
    
    struct Line
    {
        int y;
        int x1,x2;
        int f;
        friend bool operator < (const Line &a,const Line &b)
        {
            return a.y < b.y;
        }
    }line[MAXN];
    int x[MAXN],debug;
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].lf = x[l];
        tree[id].rf = x[r];
        tree[id].cnt = 0;
        tree[id].numseg = 0;
        tree[id].c = 0;
        tree[id].lcover = tree[id].rcover = false;
        if (l + 1 == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid,r);
    }
    
    void callen(int id)
    {
        if (tree[id].c > 0)
        {
            tree[id].cnt = tree[id].rf - tree[id].lf;
            tree[id].numseg = 1;
            tree[id].lcover = tree[id].rcover = true;
            return;
        }
        if (tree[id].l + 1 == tree[id].r)
        {
            tree[id].cnt = 0;
            tree[id].numseg = 0;
            tree[id].lcover = tree[id].rcover = false;
        }
        else
        {
           // printf("%d %d %d
    ",tree[id].cnt,tree[id * 2].cnt ,tree[id * 2 + 1].cnt);
           // printf("%d %d %d %d
    ",tree[id * 2].l,tree[id * 2].r,tree[id * 2 + 1].l,tree[id * 2 + 1].r);
            tree[id].cnt = tree[id * 2].cnt + tree[id * 2 + 1].cnt;
            tree[id].lcover = tree[id * 2].lcover;
            tree[id].rcover = tree[id * 2 + 1].rcover;
            tree[id].numseg = tree[id * 2].numseg + tree[id * 2 + 1].numseg;
            if (tree[id * 2].rcover && tree[id * 2 + 1].lcover) tree[id].numseg--;
        }
    }
    
    void update(int id,Line e)
    {
        if (tree[id].lf == e.x1 && tree[id].rf == e.x2)
        {
            tree[id].c += e.f;
           // printf("%d %d %d %d %d %d %d
    ",debug,tree[id].lf,tree[id].rf,tree[id].cnt,tree[id].c,tree[id].l,tree[id].r);
            callen(id);
            return;
        }
        if (e.x2 <= tree[id * 2].rf) update(id * 2,e);
        else if (e.x1 >= tree[id * 2 + 1].lf) update(id * 2 + 1,e);
        else
        {
            Line tmp = e;
            tmp.x2 = tree[id * 2].rf;
            update(id * 2,tmp);
            tmp = e;
            tmp.x1 = tree[id * 2 + 1].lf;
            update(id * 2 + 1,tmp);
        }
        callen(id);
    }
    
    int main()
    {
        int n;
        while (scanf("%d",&n) != EOF)
        {
            int cas = 0;
            int x1,x2,y1,y2;
            debug = 0;
            for (int i = 0 ; i < n ; i++)
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                line[cas].x1 = x1;
                line[cas].x2 = x2;
                line[cas].y = y1;
                line[cas].f = 1;
                x[cas] = x1;
                cas++;
                line[cas].x1 = x1;
                line[cas].x2 = x2;
                line[cas].y = y2;
                line[cas].f = -1;
                x[cas] = x2;
                cas++;
            }
            sort(line,line + cas);
            sort(x,x + cas);
            int num = unique(x,x + cas) - x;
            build(1,0,num - 1);
            int ret = 0,last = 0;
            for (int i = 0 ; i < cas - 1 ; i++)
            {
                debug++;
                update(1,line[i]);
                ret += tree[1].numseg * 2 * (line[i + 1].y - line[i].y);
                ret += abs(tree[1].cnt - last);
               // printf("%d %d %d %d
    ",line[i].x1,line[i].x2,line[i].y,tree[1].cnt);
               // printf("%d
    
    ",ret);
                last = tree[1].cnt;
            }
            update(1,line[cas - 1]);
            ret += abs(tree[1].cnt - last);
            printf("%d
    ",ret);
        }
        return 0;
    }
    View Code

    HDU 1542 Atlantis

    线段树扫描线举行面积并

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 210;
    const int INF = 0x3f3f3f3f;
    int N;
    
    struct node
    {
        int l,r;
        double lf,rf;
        int c;
        double cnt;
    }tree[MAXN * 4];
    
    struct Line
    {
        double x1,x2;
        double y;
        int f;
        friend bool operator < (const Line &a,const Line &b)
        {
            return a.y < b.y;
        }
    }line[MAXN];
    double x[MAXN];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].lf = x[l];
        tree[id].rf = x[r];
        tree[id].c = 0;
        tree[id].cnt = 0;
        if (l + 1 == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid,r);
    }
    
    void callen(int id)
    {
        if (tree[id].c > 0)
        {
            tree[id].cnt = tree[id].rf - tree[id].lf;
            return;
        }
        if (tree[id].l + 1 == tree[id].r)
        {
            tree[id].cnt = 0;
        }
        else
            tree[id].cnt = tree[id * 2].cnt + tree[id * 2 + 1].cnt;
    }
    
    void update(int id,Line e)
    {
        if (tree[id].lf == e.x1 && tree[id].rf == e.x2)
        {
            tree[id].c += e.f;
            callen(id);
            return;
        }
        if (tree[id * 2].rf >= e.x2) update(id * 2,e);
        else if (e.x1 >= tree[id * 2 + 1].lf) update(id * 2 + 1,e);
        else
        {
            Line tmp = e;
            tmp.x2 = tree[id * 2].rf;
            update(id * 2,tmp);
            tmp = e;
            tmp.x1 = tree[id * 2 + 1].lf;
            update(id * 2 + 1,tmp);
        }
        callen(id);
    }
    
    int main()
    {
        int kase = 1;
        while (scanf("%d",&N) != EOF)
        {
            if (N == 0) break;
            int cas = 0;
            for (int i = 0 ; i < N ; i++)
            {
                double x1,x2,y1,y2;
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                line[cas].x1 = x1;
                line[cas].x2 = x2;
                line[cas].y = y1;
                line[cas].f = 1;
                x[cas++] = x1;
                line[cas].x1 = x1;
                line[cas].x2 = x2;
                line[cas].y = y2;
                line[cas].f = -1;
                x[cas++] = x2;
            }
            sort(x,x + cas);
            sort(line,line + cas);
            int num = unique(x ,x + cas) - x;
            build(1,0,num - 1);
            double ret = 0;
            update(1,line[0]);
            for (int i = 1 ; i < cas ; i++)
            {
                ret += (line[i].y - line[i - 1].y) * tree[1].cnt;
                update(1,line[i]);
            }
            printf("Test case #%d
    ",kase++);
            printf("Total explored area: %.2lf
    
    ",ret);
        }
        return 0;
    }
    View Code

    HDU 1255 覆盖的面积

    矩形被覆盖2次以上的面积并。这个你要理解下这类问题是怎么解决的

    首先c只有的被完全区间的时候会更新,区间被覆盖一次的长度表示什么,并不是一定就只覆盖了一次,

    详细的看看callen函数。

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 2010;
    struct node
    {
        int l,r;
        int c;
        double lf,rf;
        double cnt,more;
    }tree[MAXN * 4];
    
    struct Line
    {
        double x1,x2;
        double y;
        int f;
        friend bool operator < (const Line &a,const Line &b)
        {
            return a.y < b.y;
        }
    }line[MAXN];
    double x[MAXN];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].lf = x[l];
        tree[id].rf = x[r];
        tree[id].cnt = tree[id].more = tree[id].c = 0;
        if (l + 1 == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid,r);
    }
    
    void callen(int id)
    {
        if (tree[id].c >= 2)
        {
            tree[id].more = tree[id].rf - tree[id].lf;
            return;
        }
        if (tree[id].c == 1)
        {
            tree[id].cnt = tree[id].rf - tree[id].lf;
            if (tree[id].l + 1 == tree[id].r) tree[id].more = 0;
            else tree[id].more = tree[id * 2].cnt + tree[id * 2 + 1].cnt;
        }
        else
        {
            if (tree[id].l == tree[id].r - 1)
                tree[id].cnt = tree[id].more = 0;
            else
            {
                tree[id].cnt = tree[id * 2].cnt + tree[id * 2 + 1].cnt;
                tree[id].more = tree[id * 2].more + tree[id * 2 + 1].more;
            }
        }
    }
    
    void update(int id,Line e)
    {
        if (tree[id].lf == e.x1 && tree[id].rf == e.x2)
        {
            tree[id].c += e.f;
           // printf("%d %d %d %d %d %d %d
    ",debug,tree[id].lf,tree[id].rf,tree[id].cnt,tree[id].c,tree[id].l,tree[id].r);
            callen(id);
            return;
        }
        if (e.x2 <= tree[id * 2].rf) update(id * 2,e);
        else if (e.x1 >= tree[id * 2 + 1].lf) update(id * 2 + 1,e);
        else
        {
            Line tmp = e;
            tmp.x2 = tree[id * 2].rf;
            update(id * 2,tmp);
            tmp = e;
            tmp.x1 = tree[id * 2 + 1].lf;
            update(id * 2 + 1,tmp);
        }
        callen(id);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
            int N;
            scanf("%d",&N);
            int cas = 0;
            for (int i = 0 ; i < N ; i++)
            {
                double x1,x2,y1,y2;
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                line[cas].x1 = x1;
                line[cas].x2 = x2;
                line[cas].y = y1;
                line[cas].f = 1;
                x[cas++] = x1;
                line[cas].x1 = x1;
                line[cas].x2 = x2;
                line[cas].y = y2;
                line[cas].f = -1;
                x[cas++] = x2;
            }
            sort(line,line + cas);
            sort(x,x + cas);
            int num = unique(x,x + cas) - x;
            build(1,0,num - 1);
            update(1,line[0]);
            double ret = 0;
            for (int i = 1 ; i < cas ; i++)
            {
                ret += (line[i].y - line[i - 1].y) * tree[1].more;
                update(1,line[i]);
            }
            printf("%.2lf
    ",ret);
        }
        return 0;
    }
    View Code

    HDU 3642 Get The Treasury

    线段树扫面线三维体积并,要求三次的内容。由于Z的绝对值小于500,所以可以枚举z

    然后化为2唯来做

    如何计算callen 中的once,twice,more是关键,理解很关键

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <cctype>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define PI 3.1415926535897932626
    using namespace std;
    int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
    const int MAXN = 2010;
    const int INF = 0x3f3f3f3f;
    struct node
    {
        int l,r;
        int lf,rf;
        int once,twice,more;
        int c;
    }tree[MAXN * 4];
    int x[MAXN],z[MAXN];
    
    struct Line
    {
        int y;
        int x1,x2;
        int z1,z2;
        int f;
        friend bool operator < (const Line &a,const Line &b)
        {
            return a.y < b.y;
        }
    }line[MAXN],res[MAXN];
    
    void build(int id,int l,int r)
    {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].lf = x[l];
        tree[id].rf = x[r];
        tree[id].c = 0;
        tree[id].once = tree[id].twice = tree[id].more = 0;
        if (l + 1 == r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid,r);
    }
    
    void callen(int id)
    {
        if (tree[id].c >= 3)
        {
            tree[id].more = tree[id].rf - tree[id].lf;
            tree[id].once = tree[id].twice = 0;
            return;
        }
        else if (tree[id].c == 2)
        {
            if (tree[id].l + 1 == tree[id].r)
            {
                tree[id].more = 0;
                tree[id].twice = tree[id].rf - tree[id].lf;
                tree[id].once = 0;
                return;
            }
            else
            {
                tree[id].more = tree[id * 2].once + tree[id * 2].twice + tree[id * 2].more
                            + tree[id * 2 + 1].once + tree[id * 2 + 1].twice + tree[id * 2 + 1].more;
                tree[id].twice = tree[id].rf - tree[id].lf - tree[id].more;
                tree[id].once = 0;
            }
        }
        else if (tree[id].c == 1)
        {
            if (tree[id].l + 1 == tree[id].r)
            {
                tree[id].more = tree[id].twice = 0;
                tree[id].once = tree[id].rf - tree[id].lf;
            }
            else
            {
                tree[id].more = tree[id * 2].more + tree[id * 2].twice
                        + tree[id * 2 + 1].more + tree[id * 2 + 1].twice;
                tree[id].twice = tree[id * 2].once + tree[id * 2 + 1].once;
                tree[id].once = tree[id].rf - tree[id].lf - tree[id].more - tree[id].twice;
            }
        }
        else
        {
            if (tree[id].l == tree[id].r - 1)
            {
                tree[id].more = tree[id].twice = tree[id].once = 0;
            }
            else
            {
                tree[id].more = tree[id * 2].more + tree[id * 2 + 1].more;
                tree[id].twice = tree[id * 2].twice + tree[id * 2 + 1].twice;
                tree[id].once = tree[id * 2].once + tree[id * 2 + 1].once;
            }
        }
    }
    
    void update(int id,Line e)
    {
        if (tree[id].lf == e.x1 && tree[id].rf == e.x2)
        {
            tree[id].c += e.f;
            callen(id);
            return;
        }
        if (tree[id * 2].rf >= e.x2) update(id * 2,e);
        else if (e.x1 >= tree[id * 2 + 1].lf) update(id * 2 + 1,e);
        else
        {
            Line tmp = e;
            tmp.x2 = tree[id * 2].rf;
            update(id * 2,tmp);
            tmp = e;
            tmp.x1 = tree[id * 2 + 1].lf;
            update(id * 2 + 1,tmp);
        }
        callen(id);
    }
    int main()
    {
        int T,kase = 1;
        scanf("%d",&T);
        while (T--)
        {
            int N;
            scanf("%d",&N);
            int cas = 0;
            for (int i = 0 ; i < N ; i++)
            {
                int x1,x2,y1,y2,z1,z2;
                scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
                line[cas].x1 = x1;
                line[cas].x2 = x2;
                line[cas].z1 = z1;
                line[cas].z2 = z2;
                line[cas].f = 1;
                line[cas].y = y1;
                x[cas] = x1;
                z[cas++] = z1;
    
                line[cas].x1 = x1;
                line[cas].x2 = x2;
                line[cas].z1 = z1;
                line[cas].z2 = z2;
                line[cas].f = -1;
                line[cas].y = y2;
                x[cas] = x2;
                z[cas++] = z2;
            }
            sort(line,line + cas);
            sort(x,x + cas);
            sort(z,z + cas);
            int num = unique(x,x + cas) - x;
            build(1,0,num - 1);
            int step = unique(z,z + cas) - z;
            LL ret = 0,area = 0;
            for (int i = 0 ; i < step - 1 ; i++)
            {
                int tot = 0;
                for (int j = 0 ; j < cas ; j++)
                {
                    if (line[j].z1 <= z[i] && line[j].z2 > z[i])
                        res[tot++] = line[j];
                }
                area = 0;
                update(1,res[0]);
                for (int j = 1 ; j < tot ; j++)
                {
                    area += (LL)(res[j].y - res[j - 1].y) * tree[1].more;
                    update(1,res[j]);
                }
                ret += area * (LL)(z[i + 1] - z[i]);
            }
            printf("Case %d: %I64d
    ",kase++,ret);
        }
        return 0;
    }
    View Code

    离散处理题目。求区间内不同数字的和,和不同数字的个数

    Uvalive 5970 An Average Game

    离散右端点排序每次标记上一次出现的位置

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 100100;
    #define LL long long
    struct node {
        int l,r;
        int idx;
        friend bool operator < (const node &a,const node &b) {
            if (a.r == b.r) return a.l < b.l;
            return a.r < b.r;
        }
    }src[MAXN];
    int N,Q;
    LL A[MAXN];
    pair<LL,LL>ans[MAXN ];
    
    struct treenode {
        int l,r;
        int sum;
    }tree[MAXN * 4];
    
    void build(int id,int l,int r) {
        tree[id].l = l;
        tree[id].r = r;
        tree[id].sum = 0;
        if (l >= r) return;
        int mid = (l + r) / 2;
        build(id * 2,l,mid);
        build(id * 2 + 1,mid + 1,r);
    }
    
    void update(int id,int pos,bool flag) {
        if (tree[id].l == pos && tree[id].r == pos) {
            if (flag) tree[id].sum = 0;
            else tree[id].sum = 1;
            return;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (pos <= mid) update(id * 2,pos,flag);
        else update(id * 2 + 1,pos,flag);
        tree[id].sum = tree[id * 2].sum + tree[id * 2 + 1].sum;
    }
    
    int query(int id,int l,int r) {
        if (tree[id].l >= l && tree[id].r <= r) {
            return tree[id].sum;
        }
        int mid = (tree[id].l + tree[id].r) / 2;
        if (r <= mid) return query(id * 2,l,r);
        else if (l > mid) return query(id * 2 + 1,l,r);
        else {
            return query(id * 2,l,mid) + query(id * 2 + 1,mid + 1,r);
        }
    }
    
    struct IntervalTree
    {
        LL sum[MAXN * 4];
        void build(){memset(sum,0,sizeof(sum));}
        void update(int o,int l,int r,int pos,int val)
        {
            if(l == r)
            {
                sum[o] += val;
                return;
            }
            int mid = (l + r) >> 1;
            if(pos <= mid)update(o << 1,l,mid,pos,val);
            else update(o<< 1 | 1,mid + 1,r,pos,val);
            sum[o]=sum[o << 1]+sum[o << 1 |1];
        }
        LL query(int o,int l,int r,int q1,int q2)
        {
            if(q1 <= l && r <= q2)return sum[o];
            int mid=(l + r)>>1;
            LL ans=0;
            if(q1 <= mid)ans += query(o << 1,l,mid,q1,q2);
            if(q2 > mid)ans += query(o << 1 | 1,mid + 1,r,q1,q2);
            return  ans;
        }
    }Tree;
    
    map<int,int>vis;
    int main() {
        int T,kase = 1;
        cin >> T;
        while (T--) {
            cin >> N;
            for (int i = 1 ; i <= N ; i++) cin >> A[i];
            cin >> Q;
            for (int i = 1 ; i <= Q ; i++) { cin >> src[i].l >> src[i].r; if (src[i].l > src[i].r) swap(src[i].l,src[i].r); }
            for (int i = 1 ; i <= Q ; i++) src[i].idx = i;
            vis.clear();
            sort(src + 1,src + 1 + Q);
            build(1,1,N);
            int curpos = 1;
            for (int i = 1 ; i <= Q ; i++) {
                while (curpos <= N && curpos <= src[i].r) {
                    if (vis[A[curpos]]) update(1,vis[A[curpos]],true);
                    update(1,curpos,false);
                    vis[A[curpos]] = curpos;
                    curpos++;
                }
                ans[src[i].idx].first = (LL)query(1,src[i].l,src[i].r);
            }
    
            Tree.build();
            vis.clear();
            int cur = 1;
            for(int i = 1 ; i <= Q ; i++)
            {
                for(; cur <= N && cur <= src[i].r ; cur++)
                {
                    if(vis[A[cur]])Tree.update(1,1,N,vis[A[cur]],-A[cur]);
                    Tree.update(1,1,N,cur,A[cur]);
                    vis[A[cur]] = cur;
                }
                ans[src[i].idx].second = Tree.query(1,1,N,src[i].l,src[i].r);
            }
           // for (int i = 1 ; i <= Q ; i++) cout << ans[i].first << " " << ans[i].second << endl;
            printf("Case %d:
    ",kase++);
            for (int i = 1 ; i <= Q ; i++) printf("%.6lf
    ",(1.0 * ans[i].second) / (1.0 * ans[i].first));
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    MFC单文档框架分析及执行流程(转)
    MFC不同工程(解决方案)之间对话框资源的复制与重用方法(转)
    【DLL】动态库的创建,隐式加载和显式加载(转)
    H264协议(转)
    YUV颜色编码解析(转)
    windows下常用快捷键(转)
    【Sqlite3】SQLITE3使用总结(转)
    C++11 自动释放锁(转)
    alt+ F8 设置无效(转)
    Invalidate()(转)
  • 原文地址:https://www.cnblogs.com/Commence/p/4877241.html
Copyright © 2011-2022 走看看