zoukankan      html  css  js  c++  java
  • 线段树

    感觉线段树一直学的不好,从开始学到现在换了很多风格,模板其实不是问题,关键是还是思路吧。

    从水题,开始再来一遍。

    HDU 1166 敌兵步阵

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define MOD 1000000009
    #define N 50000
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int p[4*N];
    void pushup(int rt)
    {
        p[rt] = p[rt<<1] + p[rt<<1|1];
    }
    void build(int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            scanf("%d",&p[rt]);
            return ;
        }
        m = (l+r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int x,int sc,int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            p[rt] += sc;
            return ;
        }
        m = (l+r)>>1;
        if(x <= m)
        update(x,sc,lson);
        else
        update(x,sc,rson);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        int m,sum = 0;
        if(l >= L&&r <= R)
        {
            return p[rt];
        }
        m = (l+r)>>1;
        if(L <= m)
        sum += query(L,R,lson);
        if(R > m)
        sum += query(L,R,rson);
        return sum;
    }
    int main()
    {
        int t,cas = 1,a,b,n;
        char str[101];
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            build(1,n,1);
            printf("Case %d:
    ",cas++);
            for(;;)
            {
                scanf("%s",str);
                if(str[0] == 'E') break;
                if(str[0] == 'Q')
                {
                    scanf("%d%d",&a,&b);
                    printf("%d
    ",query(a,b,1,n,1));
                }
                else if(str[0] == 'A')
                {
                    scanf("%d%d",&a,&b);
                    update(a,b,1,n,1);
                }
                else
                {
                    scanf("%d%d",&a,&b);
                    update(a,-b,1,n,1);
                }
            }
        }
        return 0;
    }
    View Code

    HDU 1698 Just a Hook

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define N 100001
    int p[4*N];
    int lz[4*N];
    void pushup(int rt)
    {
        p[rt] = p[rt<<1] + p[rt<<1|1];
    }
    void pushdown(int rt,int m)
    {
        if(lz[rt])
        {
            lz[rt<<1] = lz[rt];
            lz[rt<<1|1] = lz[rt];
            p[rt<<1] = lz[rt]*(m-(m>>1));
            p[rt<<1|1] = lz[rt]*(m>>1);
            lz[rt] = 0;
        }
    }
    void build(int l,int r,int rt)
    {
        int m;
        lz[rt] = 0;
        if(l == r)
        {
            p[rt] = 1;
            return ;
        }
        m = (l+r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        if(L <= l&&R >= r)
        {
            lz[rt] = sc;
            p[rt] = (r-l+1)*sc;
            return ;
        }
        int m = (l+r)>>1;
        pushdown(rt,r-l+1);
        if(L <= m)
        update(L,R,sc,lson);
        if(R > m)
        update(L,R,sc,rson);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        int m,sum = 0;
        if(L <= l&&R >= r)
        {
            return p[rt];
        }
        m = (l+r)>>1;
        pushdown(rt,r-l+1);
        if(L <= m)
        sum += query(L,R,lson);
        if(R > m)
        sum += query(L,R,rson);
        return sum;
    }
    int main()
    {
        int t,cas = 1,i,n,m,x,y,z;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            build(1,n,1);
            scanf("%d",&m);
            for(i = 1;i <= m;i ++)
            {
                scanf("%d%d%d",&x,&y,&z);
                update(x,y,z,1,n,1);
            }
            printf("Case %d: The total value of the hook is %d.
    ",cas++,query(1,n,1,n,1));
        }
        return 0;
    }
    View Code

     HDU 4614 Vases and Flowers

    以前用线段树+二分做的,这次换了一个思路,把插过为0,没插过为1,利用find函数,查找。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define N 50001
    int p[4*N],lz[4*N];
    void pushup(int rt)
    {
        p[rt] = p[rt<<1] + p[rt<<1|1];
    }
    void pushdown(int rt,int m)
    {
        if(lz[rt] != -1)
        {
            lz[rt<<1] = lz[rt];
            lz[rt<<1|1] = lz[rt];
            p[rt<<1] = lz[rt]*(m-(m>>1));
            p[rt<<1|1] = lz[rt]*(m>>1);
            lz[rt] = -1;
        }
    }
    void build(int l,int r,int rt)
    {
        int m;
        lz[rt] = -1;
        if(l == r)
        {
            p[rt] = 1;
            return ;
        }
        m = (l + r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            lz[rt] = sc;
            p[rt] = (r-l+1)*sc;
            return ;
        }
        pushdown(rt,r-l+1);
        m = (l + r)>>1;
        if(L <= m)
        update(L,R,sc,lson);
        if(R > m)
        update(L,R,sc,rson);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        int m,sum = 0;
        if(l >= L&&r <= R)
        {
            return p[rt];
        }
        pushdown(rt,r-l+1);
        m = (l+r)>>1;
        if(L <= m)
        sum += query(L,R,lson);
        if(R > m)
        sum += query(L,R,rson);
        return sum;
    }
    int find(int x,int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            return l;
        }
        pushdown(rt,r-l+1);
        m = (l+r)>>1;
        if(x <= p[rt<<1])
        return find(x,lson);
        else
        return find(x-p[rt<<1],rson);
    }
    int main()
    {
        int t,n,m,i,k,a,b,temp,l,r;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            build(0,n-1,1);
            for(i = 1;i <= m;i ++)
            {
                scanf("%d%d%d",&k,&a,&b);
                if(k == 1)
                {
                    temp = query(a,n-1,0,n-1,1);
                    if(temp == 0)
                    {
                        printf("Can not put any one.
    ");
                        continue;
                    }
                    b = min(b,temp);
                    if(a == 0)
                    temp = 0;
                    else
                    temp = query(0,a-1,0,n-1,1);
                    l = find(temp+1,0,n-1,1);
                    r = find(temp+b,0,n-1,1);
                    printf("%d %d
    ",l,r);
                    update(l,r,0,0,n-1,1);
                }
                else
                {
                    printf("%d
    ",b-a+1-query(a,b,0,n-1,1));
                    update(a,b,1,0,n-1,1);
                }
            }
            printf("
    ");
        }
        return 0;
    }
    View Code

     ZOJ 1610 Count the Colors

    注意这是一段的染色。挺简单的,1Y.

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define N 8001
    int p[4*N],lz[4*N];
    int flag[N],o[N];
    void pushdown(int rt)
    {
        if(lz[rt] != -1)
        {
            lz[rt<<1] = lz[rt];
            lz[rt<<1|1] = lz[rt];
            p[rt<<1] = lz[rt];
            p[rt<<1|1] = lz[rt];
            lz[rt] = -1;
        }
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            lz[rt] = sc;
            p[rt] = sc;
            return ;
        }
        pushdown(rt);
        m = (l + r) >>1;
        if(L <= m)
        update(L,R,sc,lson);
        if(R > m)
        update(L,R,sc,rson);
    }
    void query(int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            o[l] = p[rt];
            return ;
        }
        m = (l + r)>>1;
        pushdown(rt);
        query(lson);
        query(rson);
    }
    int main()
    {
        int n,i,x1,x2,c;
        while(scanf("%d",&n)!=EOF)
        {
            memset(flag,0,sizeof(flag));
            memset(o,0,sizeof(o));
            memset(p,-1,sizeof(p));
            memset(lz,-1,sizeof(lz));
            for(i = 0;i < n;i ++)
            {
                scanf("%d%d%d",&x1,&x2,&c);
                if(x1 <= x2-1)
                update(x1,x2-1,c,0,8000,1);
            }
            query(0,8000,1);
            for(i = 1;i <= 8000;i ++)
            {
                if(o[i] != o[i-1])
                {
                    if(o[i-1] != -1)
                    flag[o[i-1]] ++;
                }
            }
            if(o[8000] != -1)
            flag[o[8000]] ++;
            for(i = 0;i <= 8000;i ++)
            {
                if(flag[i])
                printf("%d %d
    ",i,flag[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    View Code

     HDU 4302 Holedox Eating

    和4614类似,注意待在原地的时候,方向不变。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define N 100001
    int p[4*N];
    void pushup(int rt)
    {
        p[rt] = p[rt<<1] + p[rt<<1|1];
    }
    void update(int x,int sc,int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            p[rt] += sc;
            return ;
        }
        m = (l+r)>>1;
        if(x <= m)
        update(x,sc,lson);
        else
        update(x,sc,rson);
        pushup(rt);
    }
    int find(int x,int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            return l;
        }
        m = (l + r) >>1;
        if(x <= p[rt<<1])
        return find(x,lson);
        else
        return find(x-p[rt<<1],rson);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        int m,sum = 0;
        if(l >= L&&r <= R)
        {
            return p[rt];
        }
        m = (l + r)>>1;
        if(L <= m)
        sum += query(L,R,lson);
        if(R > m)
        sum += query(L,R,rson);
        return sum;
    }
    int Abs(int x)
    {
        if(x < 0)
        return -x;
        return x;
    }
    int main()
    {
        int t,n,m,cas = 1,i,k,x,pre,l,r,flag,temp;
        scanf("%d",&t);
        while(t--)
        {
            memset(p,0,sizeof(p));
            int ans = 0;
            scanf("%d%d",&n,&m);
            pre = 0;
            flag = -1;
            for(i = 0;i < m;i ++)
            {
                scanf("%d",&k);
                if(k == 0)
                {
                    scanf("%d",&x);
                    update(x,1,0,n,1);
                }
                else
                {
                    temp = query(0,pre,0,n,1);
                    if(p[1] == 0) continue;
                    if(temp == 0)
                    l = -100000000;
                    else
                    l = find(temp,0,n,1);
                    if(p[1] == temp)
                    r = 1000000000;
                    else
                    r = find(temp+1,0,n,1);
                    int te = pre;
                    if(l == pre)
                    {
                        update(l,-1,0,n,1);
                        continue;
                    }
                    if(pre - l > r - pre)
                    {
                        pre = r;
                        flag = 1;
                        update(r,-1,0,n,1);
                    }
                    else if(pre - l < r - pre)
                    {
                        pre = l;
                        flag = 0;
                        update(l,-1,0,n,1);
                    }
                    else if(flag)
                    {
                        pre = r;
                        update(r,-1,0,n,1);
                    }
                    else
                    {
                        pre = l;
                        update(l,-1,0,n,1);
                    }
                    ans += Abs(te-pre);
                }
            }
            printf("Case %d: %d
    ",cas++,ans);
        }
        return 0;
    }
    View Code

    HDU 1394 Minimum Inversion Number

    求逆序数,当移动的时候,我居然毫无想法,看了题解发现如此简单啊....菜啊!!!!

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define N 10001
    int p[4*N];
    int flag[N];
    int s[N];
    void pushup(int rt)
    {
        p[rt] = p[rt<<1] + p[rt<<1|1];
    }
    void update(int x,int sc,int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            p[rt] = sc;
            return ;
        }
        m = (l + r)>>1;
        if(x <= m)
        update(x,sc,lson);
        else
        update(x,sc,rson);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        int m,sum = 0;
        if(l >= L&&r <= R)
        {
            return p[rt];
        }
        m = (l + r)>>1;
        if(L <= m)
        sum += query(L,R,lson);
        if(R > m)
        sum += query(L,R,rson);
        return sum;
    }
    int main()
    {
        int n,i,sum,ans;
        while(scanf("%d",&n)!=EOF)
        {
            memset(flag,0,sizeof(flag));
            memset(p,0,sizeof(p));
            for(i = 0;i < n;i ++)
            {
                scanf("%d",&s[i]);
                flag[s[i]] = i;
            }
            sum = 0;
            for(i = n-1;i >= 0;i --)
            {
                if(flag[i] != 0)
                {
                    sum += query(0,flag[i]-1,0,n-1,1);
                }
                update(flag[i],1,0,n-1,1);
            }
            ans = sum;
            for(i = 0;i < n;i ++)
            {
                sum -= s[i];
                sum += n-1-s[i];
                ans = min(ans,sum);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

     POJ 3264 Balanced Lineup

    模板题。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define N 50001
    int minz[4*N],maxz[4*N];
    void pushup(int rt)
    {
        minz[rt] = min(minz[rt<<1],minz[rt<<1|1]);
        maxz[rt] = max(maxz[rt<<1],maxz[rt<<1|1]);
    }
    void build(int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            scanf("%d",&minz[rt]);
            maxz[rt] = minz[rt];
            return ;
        }
        m = (l + r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    int qmax(int L,int R,int l,int r,int rt)
    {
        int m,ans = -1;
        if(l >= L&&r <= R)
        {
            return maxz[rt];
        }
        m = (l + r)>>1;
        if(L <= m)
        ans = max(ans,qmax(L,R,lson));
        if(R > m)
        ans = max(ans,qmax(L,R,rson));
        return ans;
    }
    int qmin(int L,int R,int l,int r,int rt)
    {
        int m,ans = 100000000;
        if(l >= L&&r <= R)
        {
            return minz[rt];
        }
        m = (l + r)>>1;
        if(L <= m)
        ans = min(ans,qmin(L,R,lson));
        if(R > m)
        ans = min(ans,qmin(L,R,rson));
        return ans;
    }
    int main()
    {
        int n,m,i,x,y;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            build(1,n,1);
            for(i = 0;i < m;i ++)
            {
                scanf("%d%d",&x,&y);
                printf("%d
    ",qmax(x,y,1,n,1)-qmin(x,y,1,n,1));
            }
        }
        return 0;
    }
    View Code

     ZOJ 3772 Calculate the Function

    这题主要是想到矩阵+线段树,就好做了。注意矩阵乘法的顺序会影响最后的结果,倒这把矩阵乘起来。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    using namespace std;
    #define N 100001
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define MOD 1000000007
    #define LL long long 
    struct node
    {
        LL s[2][2];
    } mat[4*N];
    int p[4*N];
    int num;
    node mul(node a,node b)
    {
        node c;
        int i,j,k;
        for(i = 0; i < 2; i ++)
        {
            for(j = 0; j < 2; j ++)
            c.s[i][j] = 0;
        }
        for(i = 0; i < 2; i ++)
        {
            for(j = 0; j < 2; j ++)
            {
                for(k = 0; k < 2; k ++)
                {
                    c.s[i][j] += (a.s[i][k] * b.s[k][j])%MOD;
                    c.s[i][j] %= MOD;
                }
            }
        }
        return c;
    }
    void pushup(int rt)
    {
        mat[rt] = mul(mat[rt<<1|1],mat[rt<<1]);
    }
    void build(int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            scanf("%d",&mat[rt].s[0][1]);
            p[num++] = mat[rt].s[0][1];
            mat[rt].s[0][0] = 1;
            mat[rt].s[1][1] = 0;
            mat[rt].s[1][0] = 1;
            return ;
        }
        m = (l + r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    node query(int L,int R,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            return mat[rt];
        }
        node sum;
        sum.s[0][0] = sum.s[1][1] = 1;
        sum.s[0][1] = sum.s[1][0] = 0;
        m = (l + r)>>1;
        if(L <= m)
            sum = mul(query(L,R,lson),sum);
        if(R > m)
            sum = mul(query(L,R,rson),sum);
        return sum;
    }
    int main()
    {
        int t,n,m,i,l,r;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            num = 1;
            build(1,n,1);
            for(i = 0; i < m; i ++)
            {
                scanf("%d%d",&l,&r);
                if(r == l)
                    printf("%d
    ",p[l]);
                else if(r == l+1)
                    printf("%d
    ",p[r]);
                else
                {
                    node ans;
                    ans = query(l+2,r,1,n,1);
                    printf("%d
    ",((p[l+1]*ans.s[0][0])%MOD + (p[l]*ans.s[0][1])%MOD)%MOD);
                }
            }
        }
        return 0;
    }
    View Code

     POJ 3225 Help with Intervals

    看的宝哥的题解,这题最难在于异或,用俩延迟标记,解决的。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    using namespace std;
    #define N 200000
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define MOD 1000000007
    #define LL long long
    int lz[4*N],turn[4*N];
    int hash[N];
    void pushdown(int rt)
    {
        if(lz[rt] != -1)
        {
            lz[rt<<1] = lz[rt<<1|1] = lz[rt];
            turn[rt<<1] = turn[rt<<1|1] = turn[rt];
            lz[rt] = -1;
            turn[rt] = 0;
        }
        if(turn[rt])
        {
            if(lz[rt<<1] != -1)
            lz[rt<<1] ^= 1;
            else
            turn[rt<<1] ^= 1;
            if(lz[rt<<1|1] != -1)
            lz[rt<<1|1] ^= 1;
            else
            turn[rt<<1|1] ^= 1;
            turn[rt] = 0;
        }
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            if(sc == 2)
            {
                if(lz[rt] != -1) lz[rt] ^= 1;
                else turn[rt] ^= 1;
            }
            else
            {
                lz[rt] = sc;
                turn[rt] = 0;
            }
            return ;
        }
        pushdown(rt);
        m = (l + r)>>1;
        if(L <= m)
        update(L,R,sc,lson);
        if(R > m)
        update(L,R,sc,rson);
    }
    void query(int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            if(lz[rt] == 1)
            hash[l] = 1;
            return ;
        }
        pushdown(rt);
        m = (l + r)>>1;
        query(lson);
        query(rson);
    }
    int main()
    {
        char le,ri;
        char ch[10];
        //freopen("a.txt","r",stdin);
        int l,r,n,i;
        n = 65537*2;
        while(scanf("%s%*c%c%d,%d%c%*c",ch,&le,&l,&r,&ri)!=EOF)
        {
            if(le == '(')
               l = l*2 + 1;
            else
               l = l*2;
            if(ri == ')')
               r = r*2 - 1;
            else
               r = r*2;
            if(ch[0] == 'U')
            {
                update(l,r,1,0,n,1);
            }
            else if(ch[0] == 'I')
            {
                if(l-1 >= 0)
                update(0,l-1,0,0,n,1);
                update(r+1,n,0,0,n,1);
            }
            else if(ch[0] == 'D')
            {
                update(l,r,0,0,n,1);
            }
            else if(ch[0] == 'C')
            {
                if(l-1 >= 0)
                update(0,l-1,0,0,n,1);
                update(r+1,n,0,0,n,1);
                update(l,r,2,0,n,1);
            }
            else
            {
                update(l,r,2,0,n,1);
            }
        }
        query(0,n,1);
        int flag = 0;
        l = r = -1;
        for(i = 0;i <= n;i ++)
        {
            if(hash[i])
            {
                if(l == -1) l = i;
                r = i;
            }
            else
            {
                if(l != -1)
                {
                    if(flag) printf(" ");
                    flag = 1;
                    if(l%2)
                    printf("(%d,",l/2);
                    else
                    printf("[%d,",l/2);
                    if(r%2)
                    printf("%d)",(r+1)/2);
                    else
                    printf("%d]",r/2);
                    l = -1;
                }
            }
        }
        if(flag == 0) printf("empty set");
        printf("
    ");
        return 0;
    }
    View Code

     HDU 4747 Mex 

    挺好的一个题,不过貌似和我木啥关系。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 300001
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define MOD 1000000007
    #define LL __int64
    int p[N];
    int s[N];
    LL sum[4*N];
    int maxz[4*N];
    LL lz[4*N];
    int flag[N];
    int o[2*N];
    void pushup(int rt)
    {
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
        maxz[rt] = max(maxz[rt<<1],maxz[rt<<1|1]);
    }
    void pushdown(int rt,int m)
    {
        if(lz[rt] != -1)
        {
            lz[rt<<1] = lz[rt<<1|1] = lz[rt];
            sum[rt<<1] = lz[rt]*(m-(m>>1));
            sum[rt<<1|1] = lz[rt]*(m>>1);
            maxz[rt<<1] = maxz[rt<<1|1] = lz[rt];
            lz[rt] = -1;
        }
    }
    void build(int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            sum[rt] = s[l];
            maxz[rt] = s[l];
            return ;
        }
        m = (l + r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            lz[rt] = sc;
            sum[rt] = sc*(r-l+1);
            maxz[rt] = sc;
            return ;
        }
        pushdown(rt,r-l+1);
        m = (l + r)>>1;
        if(L <= m)
        update(L,R,sc,lson);
        if(R > m)
        update(L,R,sc,rson);
        pushup(rt);
    }
    int find(int x,int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            if(sum[rt] > x)
            return l;
            else
            return l+1;
        }
        pushdown(rt,r-l+1);
        m = (l + r)>>1;
        if(x < maxz[rt<<1])
        return find(x,lson);
        else
        return find(x,rson);
    }
    LL query(int L,int R,int l,int r,int rt)
    {
        LL ans = 0;
        if(l >= L&&r <= R)
        {
            return sum[rt];
        }
        int m;
        m = (l + r)>>1;
        pushdown(rt,r-l+1);
        if(L <= m)
        ans += query(L,R,lson);
        if(R > m)
        ans += query(L,R,rson);
        return ans;
    }
    int main()
    {
        int i,n,temp,l,r;
        LL ans;
        while(scanf("%d",&n)!=EOF)
        {
            if(n == 0) break;
            memset(o,0,sizeof(o));
            memset(lz,-1,sizeof(lz));
            memset(sum,0,sizeof(sum));
            for(i = 1;i <= n;i ++)
            {
                scanf("%d",&p[i]);
            }
            map<int,int> mp;
            for(i = n;i >= 1;i --)
            {
                if(mp.find(p[i]) != mp.end())
                flag[i] = mp[p[i]];
                else
                flag[i] = n + 1;
                mp[p[i]] = i;
            }
            temp = 0;
            ans = 0;
            for(i = 1;i <= n;i ++)
            {
                if(p[i] < 2*N)
                o[p[i]] = 1;
                while(o[temp]) temp ++;
                s[i] = temp;
                ans += temp;
            }
            build(1,n,1);
            for(i = 1;i <= n;i ++)
            {
                update(1,i,0,1,n,1);
                l = find(p[i],1,n,1);
                r = flag[i] - 1;
                if(l <= r)
                update(l,r,p[i],1,n,1);
                ans += query(1,n,1,n,1);
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code

     HDU 4027 Can you answer these queries?

    想想,就会发现一个性质...

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 100001
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define MOD 10007
    #define LL __int64
    LL sum[4*N];
    void pushup(int rt)
    {
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    void build(int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            scanf("%I64d",&sum[rt]);
            return ;
        }
        m = (l + r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int L,int R,int l,int r,int rt)
    {
        int m;
        if(sum[rt] == r-l+1)
        {
            return ;
        }
        if(l == r)
        {
            sum[rt] = sqrt(sum[rt]*1.0);
            return ;
        }
        m = (l + r)>>1;
        if(L <= m)
        update(L,R,lson);
        if(R > m)
        update(L,R,rson);
        pushup(rt);
    }
    LL query(int L,int R,int l,int r,int rt)
    {
        int m;
        LL ans = 0;
        if(l >= L&&r <= R)
        {
            return sum[rt];
        }
        m = (l + r)>>1;
        if(L <= m)
        ans += query(L,R,lson);
        if(R > m)
        ans += query(L,R,rson);
        return ans;
    }
    int main()
    {
        int n,m,i,k,cas = 1,a,b;
        while(scanf("%d",&n)!=EOF)
        {
           build(1,n,1);
           scanf("%d",&m);
           printf("Case #%d:
    ",cas++);
           for(i = 0;i < m;i ++)
           {
               scanf("%d%d%d",&k,&a,&b);
               if(a > b) swap(a,b);
               if(k == 0)
               {
                   update(a,b,1,n,1);
               }
               else
               {
                   printf("%I64d
    ",query(a,b,1,n,1));
               }
           }
           printf("
    ");
        }
        return 0;
    }
    View Code

     HDU 4578 Transformation

    非常麻烦的一个题,两个lz的经典题目,各种卡常数。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 200001
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define MOD 10007
    #define LL __int64
    int mul[4*N];
    int add[4*N];
    int sum[3][4*N];
    inline int input()
    {
        int r=0;
        char c;
        c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') r=r*10+c-'0',c=getchar();
        return r;
    }
    void pushup(int rt)
    {
        int i;
        for(i = 0; i < 3; i ++)
            sum[i][rt] = (sum[i][rt<<1] + sum[i][rt<<1|1])%MOD;
    }
    void fun(int rt,int tmul,int tadd,int len)
    {
        int i,ans = 0,temp;
        int pa[4],pm[4];
        pa[0] = pm[0] = 1;
        for(i = 1;i < 4;i ++)
        {
            pa[i] = (pa[i-1]*tadd)%MOD;
            pm[i] = (pm[i-1]*tmul)%MOD;
        }
        for(i = 0; i < 3; i ++)
        {
            if(i == 0) temp = 1;
            else temp = 3;
            ans += ((((temp*pa[i])%MOD*pm[3-i])%MOD)*sum[2-i][rt])%MOD;
            ans %= MOD;
        }
        sum[2][rt] = (ans + len*pa[3]%MOD)%MOD;
        sum[1][rt] = (pm[2]*sum[1][rt])%MOD + (((2*tmul*tadd)%MOD)*sum[0][rt])%MOD + (len*pa[2])%MOD;
        sum[1][rt] %= MOD;
        sum[0][rt] = (tmul*sum[0][rt])%MOD + (len*tadd)%MOD;
        sum[0][rt] %= MOD;
    }
    void pushdown(int rt,int m)
    {
        if(mul[rt] != 1)
        {
            mul[rt<<1] = (mul[rt<<1]*mul[rt])%MOD;
            mul[rt<<1|1] = (mul[rt<<1|1]*mul[rt])%MOD;
            add[rt<<1] = (add[rt<<1]*mul[rt])%MOD;
            add[rt<<1|1] = (add[rt<<1|1]*mul[rt])%MOD;
            fun(rt<<1,mul[rt],0,m-(m>>1));
            fun(rt<<1|1,mul[rt],0,m>>1);
            mul[rt] = 1;
        }
        if(add[rt] != 0)
        {
            add[rt<<1] = (add[rt<<1]+add[rt])%MOD;
            add[rt<<1|1] = (add[rt<<1|1]+add[rt])%MOD;
            fun(rt<<1,1,add[rt],m-(m>>1));
            fun(rt<<1|1,1,add[rt],m>>1);
            add[rt] = 0;
        }
    }
    void build(int l,int r,int rt)
    {
        int m,i;
        add[rt] = 0;
        mul[rt] = 1;
        if(l == r)
        {
            for(i = 0;i < 3;i ++)
            sum[i][rt] = 0;
            return ;
        }
        m = (l + r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int L,int R,int tmul,int tadd,int l,int r,int rt)
    {
        int m,len;
        if(l >= L&&r <= R)
        {
            add[rt] = (tmul*add[rt] + tadd)%MOD;
            mul[rt] = (tmul*mul[rt])%MOD;
            len = (r-l+1);
            fun(rt,tmul,tadd,len);
            return ;
        }
        m = (l + r)>>1;
        pushdown(rt,r-l+1);
        if(L <= m)
            update(L,R,tmul,tadd,lson);
        if(R > m)
            update(L,R,tmul,tadd,rson);
        pushup(rt);
    }
    int query(int L,int R,int sc,int l,int r,int rt)
    {
        int m,ans = 0;
        if(l >= L&&r <= R)
        {
            return sum[sc][rt];
        }
        m = (l + r)>>1;
        pushdown(rt,r-l+1);
        if(L <= m)
            ans = (ans + query(L,R,sc,lson))%MOD;
        if(R > m)
            ans = (ans + query(L,R,sc,rson))%MOD;
        return ans;
    }
    int main()
    {
        int n,m,i,k,x,y,c;
        while(1)
        {
            n = input();
            m = input();
            if(n == 0&&m == 0)
                break;
            build(1,n,1);
            for(i = 0; i < m; i ++)
            {
                k = input();
                x = input();
                y = input();
                c = input();
                if(k == 1)
                {
                    update(x,y,1,c,1,n,1);
                }
                else if(k == 2)
                {
                    update(x,y,c,0,1,n,1);
                }
                else if(k == 3)
                {
                    update(x,y,0,c,1,n,1);
                }
                else
                {
                    printf("%d
    ",query(x,y,c-1,1,n,1));
                }
            }
        }
        return 0;
    }
    View Code

     HDU 4553 约会安排

    本来是应该1Y的题目,结果一个i写成了rt,让我一直RE,我盲cha了半天,没检查出错...哎呀,我不能忍啊....

    这题思路就是标记最大连续的,左边,右边,延迟。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 101000
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int lbd[2][4*N],rbd[2][4*N];
    int maxz[2][4*N],lz[2][4*N];
    void pushup(int i,int rt,int m)
    {
        maxz[i][rt] = max(maxz[i][rt<<1],maxz[i][rt<<1|1]);
        maxz[i][rt] = max(maxz[i][rt],rbd[i][rt<<1] + lbd[i][rt<<1|1]);
        if(lbd[i][rt<<1] == m - (m>>1))
        lbd[i][rt] =  lbd[i][rt<<1] + lbd[i][rt<<1|1];
        else
        lbd[i][rt] = lbd[i][rt<<1];
        if(rbd[i][rt<<1|1] == m>>1)
        rbd[i][rt] = rbd[i][rt<<1|1] + rbd[i][rt<<1];
        else
        rbd[i][rt] = rbd[i][rt<<1|1];
    }
    void pushdown(int i,int rt,int m)
    {
        if(lz[i][rt] != -1)
        {
            lz[i][rt<<1] = lz[i][rt<<1|1] = lz[i][rt];
            maxz[i][rt<<1] = (m-(m>>1))*lz[i][rt];
            maxz[i][rt<<1|1] = (m>>1)*lz[i][rt];
            lbd[i][rt<<1] = (m-(m>>1))*lz[i][rt];
            lbd[i][rt<<1|1] = (m>>1)*lz[i][rt];
            rbd[i][rt<<1] = (m-(m>>1))*lz[i][rt];
            rbd[i][rt<<1|1] = (m>>1)*lz[i][rt];
            lz[i][rt] = -1;
        }
    }
    void build(int l,int r,int rt)
    {
        int m,i;
        lz[0][rt] = -1;
        lz[1][rt] = -1;
        if(l == r)
        {
            for(i = 0;i < 2;i ++)
            {
                lbd[i][rt] = 1;
                rbd[i][rt] = 1;
                maxz[i][rt] = 1;
            }
            return ;
        }
        m = (l + r)>>1;
        build(lson);
        build(rson);
        for(i = 0;i < 2;i ++)
        pushup(i,rt,r-l+1);
    }
    void update(int i,int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            maxz[i][rt] = sc*(r-l+1);
            lbd[i][rt] = sc*(r-l+1);
            rbd[i][rt] = sc*(r-l+1);
            lz[i][rt] = sc;
            return ;
        }
        m = (l + r)>>1;
        pushdown(i,rt,r-l+1);
        if(L <= m)
        update(i,L,R,sc,lson);
        if(R > m)
        update(i,L,R,sc,rson);
        pushup(i,rt,r-l+1);
    }
    int find(int i,int x,int l,int r,int rt)
    {
       int m = (l + r)>>1;
       pushdown(i,rt,r-l+1);
       if(maxz[i][rt] < x)
       return -1;
       if(l == r)
       {
           return l;
       }
       if(maxz[i][rt<<1] >= x)
       {
           return find(i,x,lson);
       }
       else if(rbd[i][rt<<1] + lbd[i][rt<<1|1] >= x)
       {
           return m - rbd[i][rt<<1] + 1;
       }
       return find(i,x,rson);
    }
    int main()
    {
        int t,n,m,cas = 1,temp,i,a,b;
        char str[1001];
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            build(1,n,1);
            printf("Case %d:
    ",cas++);
            for(i = 0;i < m;i ++)
            {
                scanf("%s",str);
                if(str[0] == 'D')
                {
                    scanf("%d",&a);
                    temp = find(0,a,1,n,1);
                    if(temp > 0)
                    {
                        update(0,temp,temp+a-1,0,1,n,1);
                        printf("%d,let's fly
    ",temp);
                    }
                    else
                    {
                        printf("fly with yourself
    ");
                    }
                }
                else if(str[0] == 'N')
                {
                    scanf("%d",&a);
                    temp = find(0,a,1,n,1);
                    if(temp > 0)
                    {
                        update(0,temp,temp+a-1,0,1,n,1);
                        update(1,temp,temp+a-1,0,1,n,1);
                        printf("%d,don't put my gezi
    ",temp);
                        continue;
                    }
                    temp = find(1,a,1,n,1);
                    if(temp > 0)
                    {
                        update(0,temp,temp+a-1,0,1,n,1);
                        update(1,temp,temp+a-1,0,1,n,1);
                        printf("%d,don't put my gezi
    ",temp);
                        continue;
                    }
                    printf("wait for me
    ");
                }
                else
                {
                    scanf("%d%d",&a,&b);
                    update(0,a,b,1,1,n,1);
                    update(1,a,b,1,1,n,1);
                    printf("I am the hope of chinese chengxuyuan!!
    ");
                }
            }
        }
        return 0;
    }
    View Code

    HDU 4288 Coder

    耐下心来想想,就应该想出来了。不是延迟,就是标记什么的。难得的1Y。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define LL __int64
    #define N 100100
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int que[200001];
    LL sum[5][4*N];
    int flag[4*N];
    int q1[N];
    int q2[N];
    int bin(int x,int n)
    {
        int str,end,mid;
        str = 0;
        end = n;
        while(str <= end)
        {
            mid = (str + end)/2;
            if(que[mid] == x)
            return mid;
            else if(que[mid] > x)
            end = mid - 1;
            else
            str = mid + 1;
        }
        return mid;
    }
    void pushup(int rt)
    {
        int i,x;
        x = flag[rt<<1];
        flag[rt] = (flag[rt<<1] + flag[rt<<1|1]) % 5;
        for(i = 0;i < 5;i ++)
        {
            sum[(i+x)%5][rt] = sum[(i+x)%5][rt<<1] + sum[i][rt<<1|1];
        }
    }
    void update(int x,int sc,int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            flag[rt] += sc;
            if(sc == 1)
            sum[1][rt] = que[x];
            else
            sum[1][rt] = 0;
            return ;
        }
        m = (l + r)>>1;
        if(x <= m)
        update(x,sc,lson);
        else
        update(x,sc,rson);
        pushup(rt);
    }
    int main()
    {
        int n,i,k,m;
        char str[10];
        while(scanf("%d",&n)!=EOF)
        {
            m = 0;
            memset(flag,0,sizeof(flag));
            memset(sum,0,sizeof(sum));
            for(i = 0;i < n;i ++)
            {
                scanf("%s",str);
                if(str[0] == 'a')
                {
                    scanf("%d",&q2[i]);
                    que[m++] = q2[i];
                    q1[i] = 1;
                }
                else if(str[0] == 'd')
                {
                    scanf("%d",&q2[i]);
                    q1[i] = 2;
                }
                else
                {
                    q1[i] = 3;
                }
            }
            sort(que,que+m);
            k = 1;
            for(i = 1;i < m;i ++)
            {
                if(que[i] != que[i-1])
                que[k++] = que[i];
            }
            for(i = 0;i < n;i ++)
            {
                if(q1[i] == 1)
                {
                    int pos = bin(q2[i],k-1);
                    update(pos,1,0,k-1,1);
                }
                else if(q1[i] == 2)
                {
                    int pos = bin(q2[i],k-1);
                    update(pos,-1,0,k-1,1);
                }
                else
                {
                    printf("%I64d
    ",sum[3][1]);
                }
            }
        }
        return 0;
    }
    View Code

     SGU 311 Ice-cream Tycoon

    这题写起来比较麻烦,恰好可以进行一个成段染色,并且不影响sum...sum存价格的和,p存数量的和,单点更新+成段更新+离散化,不离散化会MLE。错的飞起,错了很多次。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define LL __int64
    #define N 201000
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    LL sum[4*N];
    LL p[4*N];
    int lz[4*N];
    LL que[N];
    LL q[3][N];
    void pushup(int rt)
    {
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
        p[rt] = p[rt<<1] + p[rt<<1|1];
    }
    void pushdown(int rt,int m)
    {
        if(lz[rt])
        {
            lz[rt<<1] = lz[rt<<1|1] = lz[rt];
            sum[rt<<1] = sum[rt<<1|1] = 0;
            p[rt<<1] = p[rt<<1|1] = 0;
            lz[rt] = 0;
        }
    }
    void update(int x,int sc,int l,int r,int rt)
    {
        int m;
        if(l == r)
        {
            p[rt] += sc;
            sum[rt] += (LL)sc*que[l];
            return ;
        }
        m = (l + r)>>1;
        pushdown(rt,r-l+1);
        if(x <= m)
            update(x,sc,lson);
        else
            update(x,sc,rson);
        pushup(rt);
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            lz[rt] = sc;
            sum[rt] = 0;
            p[rt] = 0;
            return ;
        }
        m = (l + r)>>1;
        pushdown(rt,r-l+1);
        if(L <= m)
            update(L,R,sc,lson);
        if(R > m)
            update(L,R,sc,rson);
        pushup(rt);
    }
    LL query1(int L,int R,int l,int r,int rt)
    {
        int m;
        LL ans = 0;
        if(l >= L&&r <= R)
        {
            return p[rt];
        }
        m = (l + r)>>1;
        pushdown(rt,r-l+1);
        if(L <= m)
            ans += query1(L,R,lson);
        if(R > m)
            ans += query1(L,R,rson);
        return ans;
    }
    LL query2(int L,int R,int l,int r,int rt)
    {
        int m;
        LL ans = 0;
        if(l >= L&&r <= R)
        {
            return sum[rt];
        }
        m = (l + r)>>1;
        pushdown(rt,r-l+1);
        if(L <= m)
            ans += query2(L,R,lson);
        if(R > m)
            ans += query2(L,R,rson);
        return ans;
    }
    int find(LL x,int l,int r,int rt)
    {
        int m;
        m = (l + r)>>1;
        pushdown(rt,r-l+1);
        if(l == r)
        return l;
        if(p[rt<<1] >= x)
            return find(x,lson);
        return find(x-p[rt<<1],rson);
    }
    int bin(int x,int n)
    {
        int str,mid,end;
        str = 1;
        end = n;
        while(str <= end)
        {
            mid = (str + end)/2;
            if(que[mid] == x)
            return mid;
            else if(que[mid] > x)
            end = mid - 1;
            else
            str = mid + 1;
        }
        return mid;
    }
    int main()
    {
        char str[100];
        int n,temp,m,k,i;
        LL num,st,a,b;
        k = 1;
        m = 0;
        while(scanf("%s",str)!=EOF)
        {
            scanf("%I64d%I64d",&a,&b);
            if(str[0] == 'A')
            {
                q[0][m] = 0;
                que[k++] = b;
            }
            else
            q[0][m] = 1;
            q[1][m] = a;
            q[2][m] = b;
            m ++;
        }
        sort(que+1,que+k);
        n = 2;
        for(i = 2;i < k;i ++)
        {
            if(que[i] != que[i-1])
            que[n++] = que[i];
        }
        n --;
        for(i = 0;i < m;i ++)
        {
            if(q[0][i] == 0)
            {
                a = q[1][i];
                b = bin(q[2][i],n);
                update(b,a,1,n,1);
            }
            else
            {
                a = q[1][i];
                b = q[2][i];
                if(p[1] < a)
                    printf("UNHAPPY
    ");
                else
                {
                    temp = find(a,1,n,1);
                    num = 0;
                    st = 0;
                    if(temp-1 >= 1)
                    {
                        num = query1(1,temp-1,1,n,1);
                        st = query2(1,temp-1,1,n,1);
                    }
                    if((a-num)*que[temp] + st > b)
                    printf("UNHAPPY
    ");
                    else
                    {
                        if(temp-1 >= 1)
                        update(1,temp-1,1,1,n,1);
                        update(temp,-(a-num),1,n,1);
                        printf("HAPPY
    ");
                    }
                }
            }
        }
        return 0;
    }
    View Code

     HDU 1255 覆盖的面积

     做过,同类型的,但是其实并不理解,sum[0]表示只有1个矩形覆盖,sum[1]表示2个以上覆盖。如果cnt[1] = 1,此段sum[1] = 左sum[1] + 右sum[1] + 左sum[0] + 右sum[0]。利用这个就能做出来了。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    using namespace std;
    #define LL long long
    #define N 10001
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    struct node
    {
        double lx,rx,y;
        int s;
        node(){}
        node(double a,double b,double c,int d):lx(a),rx(b),y(c),s(d){}
        bool operator < (const node &S)const
        {
            return y < S.y;
        }
    }mat[N];
    double sum[2][4*N];
    int cnt[4*N];
    double que[N];
    int bin(double x,int n)
    {
        int str,end,mid;
        str = 0;
        end = n;
        while(str <= end)
        {
            mid = (str + end)/2;
            if(que[mid] == x)
            return mid;
            else if(que[mid] > x)
            end = mid - 1;
            else
            str = mid + 1;
        }
        return mid;
    }
    void pushup(int rt,int l,int r)
    {
        if(cnt[rt] == 1)
        {
            sum[1][rt] = sum[0][rt<<1] + sum[0][rt<<1|1] + sum[1][rt<<1] + sum[1][rt<<1|1];
            sum[0][rt] = que[r+1] - que[l] - sum[1][rt];
        }
        else if(cnt[rt] > 1)
        {
            sum[1][rt] = que[r+1] - que[l];
            sum[0][rt] = 0;
        }
        else if(l == r)
        {
            sum[0][rt] = sum[1][rt] = 0;
        }
        else
        {
            sum[0][rt] = sum[0][rt<<1] + sum[0][rt<<1|1];
            sum[1][rt] = sum[1][rt<<1] + sum[1][rt<<1|1];
        }
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            cnt[rt] += sc;
            pushup(rt,l,r);
            return ;
        }
        m = (l + r)>>1;
        if(L <= m)
        update(L,R,sc,lson);
        if(R > m)
        update(L,R,sc,rson);
        pushup(rt,l,r);
    }
    int main()
    {
        int t,i,n,m,k,l,r;
        double x1,y1,x2,y2;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            m = 0;
            for(i = 0;i < n;i ++)
            {
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                que[m] = x1;
                mat[m++] = node(x1,x2,y1,1);
                que[m] = x2;
                mat[m++] = node(x1,x2,y2,-1);
            }
            sort(que,que+m);
            sort(mat,mat+m);
            k = 1;
            for(i = 1;i < m;i ++)
            {
                if(que[i] != que[i-1])
                que[k++] = que[i];
            }
            memset(cnt,0,sizeof(cnt));
            memset(sum,0,sizeof(sum));
            double ans = 0.0;
            for(i = 0;i < m-1;i ++)
            {
                l = bin(mat[i].lx,k-1);
                r = bin(mat[i].rx,k-1)-1;
                if(l <= r)
                update(l,r,mat[i].s,0,k-1,1);
                ans += sum[1][1]*(mat[i+1].y-mat[i].y);
            }
            printf("%.2lf
    ",ans);
        }
        return 0;
    }
    View Code

     HDU 3642 Get The Treasury

    三维立方体,求三个及以上的体积并,注意int64,wa了几次,思路跟面积并什么的差不多。

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    #define N 3001
    #define LL __int64
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    struct point
    {
        int x,y,z;
    }p[2001];
    LL sum[3][4*N];
    int cnt[4*N];
    int zi[N];
    int que[N];
    struct node
    {
        int lx,rx,y,s;
        node(){}
        node(int a,int b,int c,int d):lx(a),rx(b),y(c),s(d){}
        bool operator < (const node &S)const
        {
            return y < S.y;
        }
    }mat[N];
    int bin(int x,int n)
    {
        int str,end,mid;
        str = 0;
        end = n;
        while(str <= end)
        {
            mid = (str + end)/2;
            if(que[mid] == x)
            return mid;
            else if(que[mid] > x)
            end = mid - 1;
            else
            str = mid + 1;
        }
        return mid;
    }
    void pushup(int rt,int l,int r)
    {
        int i;
        if(cnt[rt] >= 3)
        {
            sum[2][rt] = que[r+1] - que[l];
            sum[1][rt] = 0;
            sum[0][rt] = 0;
        }
        else if(cnt[rt] == 2)
        {
            sum[2][rt] = 0;
            for(i = 0;i < 3;i ++)
            sum[2][rt] += sum[i][rt<<1] + sum[i][rt<<1|1];
            sum[1][rt] = que[r+1] - que[l] - sum[2][rt];
            sum[0][rt] = 0;
        }
        else if(cnt[rt] == 1)
        {
            sum[2][rt] = sum[2][rt<<1] + sum[2][rt<<1|1] + sum[1][rt<<1] + sum[1][rt<<1|1];
            sum[1][rt] = sum[0][rt<<1] + sum[0][rt<<1|1];
            sum[0][rt] = que[r+1] - que[l] - sum[2][rt] - sum[1][rt];
        }
        else if(l == r)
        {
            sum[0][rt] = sum[1][rt] = sum[2][rt] = 0;
        }
        else
        {
            for(i = 0;i < 3;i ++)
            sum[i][rt] = sum[i][rt<<1] + sum[i][rt<<1|1];
        }
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            cnt[rt] += sc;
            pushup(rt,l,r);
            return ;
        }
        m = (l + r)>>1;
        if(L <= m)
        update(L,R,sc,lson);
        if(R > m)
        update(L,R,sc,rson);
        pushup(rt,l,r);
    }
    LL fun(int n)
    {
        int i,k,l,r;
        LL ans;
        k = 1;
        for(i = 1;i < n;i ++)
        {
            if(que[i] != que[i-1])
            que[k++] = que[i];
        }
        memset(sum,0,sizeof(sum));
        memset(cnt,0,sizeof(cnt));
        ans = 0;
        for(i = 0;i < n-1;i ++)
        {
            l = bin(mat[i].lx,k-1);
            r = bin(mat[i].rx,k-1)-1;
            if(l <= r)
            update(l,r,mat[i].s,0,k-1,1);
            ans += (LL)sum[2][1]*(mat[i+1].y-mat[i].y);
        }
        return ans;
    }
    int main()
    {
        int t,cas = 1,n,i,j,k,num;
        LL ans;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(i = 0;i < 2*n;i ++)
            {
                scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z);
                zi[i] = p[i].z;
            }
            sort(zi,zi+2*n);
            k = 1;
            for(i = 1;i < 2*n;i ++)
            {
                if(zi[i] != zi[i-1])
                zi[k++] = zi[i];
            }
            ans = 0;
            for(i = 0;i < k-1;i ++)
            {
                num = 0;
                for(j = 0;j < n;j ++)
                {
                    if(zi[i] >= p[j*2].z&&zi[i] < p[j*2+1].z)
                    {
                        que[num] = p[j*2].x;
                        mat[num++] = node(p[j*2].x,p[j*2+1].x,p[j*2].y,1);
                        que[num] = p[j*2+1].x;
                        mat[num++] = node(p[j*2].x,p[j*2+1].x,p[j*2+1].y,-1);
                    }
                }
                sort(que,que+num);
                sort(mat,mat+num);
                ans += (LL)fun(num)*(zi[i+1]-zi[i]);
            }
            printf("Case %d: %I64d
    ",cas++,ans);
        }
        return 0;
    }
    View Code

     SGU Kalevich Strikes Back 这个题,很特别。扫描线的时候如果下边发生覆盖,这次的线段肯定比上次的要短,所以每个矩形都有一个pre,pre的矩形-当前矩形的面积就行了,可是我写的一直有问题,看了看别人的+了一个pushup函数就过了,更新那里还是有点问题啊....

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define LL long long
    #define N 220100
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    struct node
    {
        int lx,rx,y,s,id;
        node() {}
        node(int a,int b,int c,int d,int t):lx(a),rx(b),y(c),s(d),id(t) {}
        bool operator < (const node &S)const
        {
            return y < S.y;
        }
    } mat[N];
    int lz[4*N];
    int que[N];
    int pre[N];
    int flag[N];
    LL ans[N];
    int bin(int x,int n)
    {
        int str,mid,end;
        str = 0;
        end = n;
        while(str <= end)
        {
            mid = (str + end)/2;
            if(que[mid] == x)
                return mid;
            else if(que[mid] > x)
                end = mid - 1;
            else
                str = mid + 1;
        }
        return mid;
    }
    void pushdown(int rt)
    {
        if(lz[rt])
        {
            lz[rt<<1] = lz[rt<<1|1] = lz[rt];
            lz[rt] = 0;
        }
    }
    void pushup(int rt)
    {
        if(lz[rt<<1] == lz[rt<<1|1]&&lz[rt<<1])
        {
            lz[rt] = lz[rt<<1];
            lz[rt<<1] = lz[rt<<1|1] = 0;
        }
    }
    void update(int L,int R,int sc,int l,int r,int rt)
    {
        int m;
        if(l >= L&&r <= R)
        {
            if(sc < 0)
            {
                lz[rt] = pre[-sc];
            }
            else
            {
                if(flag[sc] == 0&&lz[rt])
                {
                    pre[sc] = lz[rt];
                    flag[sc] = 1;
                    ans[lz[rt]] -= ans[sc];
                }
                lz[rt] = sc;
            }
            return ;
        }
        pushdown(rt);
        m = (l + r) >> 1;
        if(L <= m)
            update(L,R,sc,lson);
        if(R > m)
            update(L,R,sc,rson);
        pushup(rt);
    }
    int main()
    {
        int i,k,n,m,x1,x2,y1,y2,w,h,num;
        scanf("%d",&n);
        m = 0;
        num = 1;
        scanf("%d%d",&w,&h);
        x1 = w;
        y1 = 0;
        x2 = 0;
        y2 = h;
        que[m] = x1;
        ans[num++] = ((LL)x1-x2)*((LL)y2-y1);
        mat[m++] = node(x2,x1,y1,1,num-1);
        que[m] = x2;
        mat[m++] = node(x2,x1,y2,-1,num-1);
        for(i = 0; i < n; i ++)
        {
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            if(x2 > x1) swap(x2,x1);
            if(y1 > y2) swap(y1,y2);
            que[m] = x1;
            ans[num++] = ((LL)x1-x2)*((LL)y2-y1);
            mat[m++] = node(x2,x1,y1,1,num-1);
            que[m] = x2;
            mat[m++] = node(x2,x1,y2,-1,num-1);
        }
        sort(que,que+m);
        sort(mat,mat+m);
        k = 1;
        for(i = 1; i < m; i ++)
        {
            if(que[i] != que[i-1])
                que[k++] = que[i];
        }
        memset(lz,0,sizeof(lz));
        memset(pre,0,sizeof(pre));
        int l,r;
        for(i = 0; i < m-1; i ++)
        {
            l = bin(mat[i].lx,k-1);
            r = bin(mat[i].rx,k-1)-1;
            if(l <= r)
            {
                if(mat[i].s > 0)
                    update(l,r,mat[i].id,0,k-1,1);
                else
                    update(l,r,-mat[i].id,0,k-1,1);
            }
        }
        sort(ans,ans+num);
        for(i = 1; i < num; i ++)
        {
            if(i != 1)
                printf(" ");
            printf("%lld",ans[i]);
        }
        printf("
    ");
        return 0;
    }
    /*
    4
    7 7
    1 1 2 2
    1 3 4 4
    3 1 4 2
    5 1 6 6
    
    */
    View Code
  • 相关阅读:
    css 伪类
    tornado 作业 简单首页 登录页 个人中心
    tornado 作业 自定义模板 UIMethod以UIModule
    tornado 网页提交内容 展示内容作业
    tornado
    javascript
    廖雪峰官网学习js 数组
    廖雪峰官网学习js 字符串
    廖雪峰官网学习js 数据类型和变量
    协程gevent学习
  • 原文地址:https://www.cnblogs.com/naix-x/p/3746324.html
Copyright © 2011-2022 走看看