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

    1.hdu 1166 单点更新,维护区间和

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/15 19:38:46
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 500000+5
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    //线段树 的单点更新和维护区间最大值
    struct node{
        int l,r,sum;//维护区间的和
    }nod[maxn*4];
    int a[maxn];
    
    bool cmp(int a,int b){
        return a>b;
    }
    int t,n,j;
    void push_up(int i){
        nod[i].sum=nod[i<<1].sum+nod[(i<<1)|1].sum;
        //更新到父节点
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
    //    nod[i].sum=0;
        if(l==r){
            nod[i].sum=a[j++];
            //cout<<a[j-1]<<endl;
            return ;
        }
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build((i<<1)|1,mid+1,r);
        push_up(i);
    }
    void update(int i,int k,int w){
        if(nod[i].l==k&&nod[i].r==k){
            nod[i].sum+=w;
            return ;
        }
        int mid=(nod[i].l+nod[i].r)/2;
        if(k<=mid)update(i<<1,k,w);
        else update((i<<1)|1,k,w);
        push_up(i);
    }
    int quary(int i,int l,int r){
        if(nod[i].l==l&&nod[i].r==r){
            return nod[i].sum;
        }
        int mid=(nod[i].l+nod[i].r)/2;
    
        if(r<=mid) return quary(i<<1,l,r);
        else if(l>mid)return quary((i<<1)|1,l,r);
        else return quary(i<<1,l,mid)+quary((i<<1)|1,mid+1,r);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        cin>>t;
        int cnt=0;
        while(t--){
            printf("Case %d:
    ",++cnt);
            cin>>n;
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            j=1;
            build(1,1,n);
            char s[100];
            while(cin>>s){
                if(s[0]=='E')break;
                else{
                    int x,y;
                    scanf("%d %d",&x,&y);
                    if(s[0]=='A'){
                        update(1,x,y);
                    }
                    else if(s[0]=='S'){
                        update(1,x,-y);
                    }
                    else{
                        printf("%d
    ",quary(1,x,y));
                    }
                }
            }
        }
        return 0;
    }
    View Code

    2.hdu 1754 单点更新,维护区间最大值

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/8/10 18:59:05
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 200010+10
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    struct node{
        int c;
        int l,r;
    }nod[3*maxn];
    
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].c=0;
        if(l==r)return ;
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build((i<<1)|1,mid+1,r)    ;
    }
    void push_up(int i){
        nod[i].c=max(nod[i<<1].c,nod[(i<<1)|1].c);
    }
    void update(int i,int k,int val){
        if(nod[i].l==k&&nod[i].r==k){
            nod[i].c=val;
            return ;
        }
        int mid=(nod[i].l+nod[i].r)/2;
        if(k<=mid)update(i<<1,k,val);
        else update((i<<1)|1,k,val);
        push_up(i);//维护最大值
    }
    int quary(int i,int l,int r){
        if(nod[i].l==l&&nod[i].r==r)
            return nod[i].c;
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)return quary(i<<1,l,r);
        else if(l>mid)return quary((i<<1)|1,l,r);
        else return max(quary(i<<1,l,mid),quary((i<<1)|1,mid+1,r));
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int n,m,v;
        while(scanf("%d%d",&n,&m)!=EOF){
            build(1,1,n);
    
            for(int i=1;i<=n;i++){
                scanf("%d",&v);
                update(1,i,v);
            }
            char s[3];int x,y;
            for(int i=1;i<=m;i++){
                scanf("%s %d %d",&s,&x,&y);
                if(s[0]=='Q'){
                    printf("%d
    ",quary(1,x,y));
                }
                else update(1,x,y);
            }
        }
        return 0;
    }
    View Code

    3.hdu 1394 树状数组做的,逆序数

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/14 18:49:07
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 10000+10
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    int a[5002];
    int c[5002];
    int n,Sum;
    int lowbit(int i){
        return i&(-i);
    }
    void add(int i,int d){
        while(i<=n){
            c[i]+=d;
            i+=lowbit(i);
        }
    }
    int sum(int i){
        int ret=0;
        while(i>=1){
            ret+=c[i];
            i-=lowbit(i);
        }
        return ret;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        //freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        while(cin>>n){
            cle(c);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            Sum=0;
            for(int i=1;i<=n;i++){
                add(a[i]+1,1);
                Sum+=i-sum(a[i]+1);
            }
            int ans=INF;
            for(int i=1;i<=n;i++){
                Sum+=(n-1-2*a[i]);
                ans=min(ans,Sum);
            }
            printf("%d
    ",ans);
    
        }
        return 0;
    }
    View Code

    4.hdu 2795 以Y轴建立线段树 单点查询

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/14 20:07:25
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 200000+10
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    struct node{
        int l,r,w;
    }nod[4*maxn];
    int h,w,n;
    bool cmp(int a,int b){
        return a>b;
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].w=w;
        if(l==r)return ;
        int mid=(r+l)/2;
        build(i<<1,l,mid);
        build((i<<1)|1,mid+1,r);
    }
    int quary(int i,int len){
        if(nod[i].l==nod[i].r){
            nod[i].w-=len;
            return nod[i].l;//返回下标
        } 
        int b;
        //int sum1=0,sum2=0;
        if(len<=nod[i<<1].w)b=quary(i<<1,len);
        else if(len<=nod[(i<<1)|1].w)b=quary((i<<1)|1,len);
        nod[i].w=max(nod[i<<1].w,nod[(i<<1)|1].w);
        return b;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        while(cin>>h>>w>>n){
            int len;
            build(1,1,min(n,h));
            for(int i=1;i<=n;i++){
                scanf("%d",&len);
                if(nod[1].w>=len)
                    printf("%d
    ",quary(1,len));
                else printf("-1
    ");
            }
        }
        return 0;
    }
    View Code

    5.poj2828 

    Buy Tickets
    Time Limit: 4000MS   Memory Limit: 65536K
    Total Submissions: 16407   Accepted: 8174

    Description

    Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue…

    The Lunar New Year was approaching, but unluckily the Little Cat still had schedules going here and there. Now, he had to travel by train to Mianyang, Sichuan Province for the winter camp selection of the national team of Olympiad in Informatics.

    It was one o’clock a.m. and dark outside. Chill wind from the northwest did not scare off the people in the queue. The cold night gave the Little Cat a shiver. Why not find a problem to think about? That was none the less better than freezing to death!

    People kept jumping the queue. Since it was too dark around, such moves would not be discovered even by the people adjacent to the queue-jumpers. “If every person in the queue is assigned an integral value and all the information about those who have jumped the queue and where they stand after queue-jumping is given, can I find out the final order of people in the queue?” Thought the Little Cat.

    Input

    There will be several test cases in the input. Each test case consists of N + 1 lines where N (1 ≤ N ≤ 200,000) is given in the first line of the test case. The next N lines contain the pairs of valuesPosi and Vali in the increasing order of i (1 ≤ i ≤ N). For each i, the ranges and meanings of Posi and Vali are as follows:

    • Posi ∈ [0, i − 1] — The i-th person came to the queue and stood right behind the Posi-th person in the queue. The booking office was considered the 0th person and the person at the front of the queue was considered the first person in the queue.
    • Vali ∈ [0, 32767] — The i-th person was assigned the value Vali.

    There no blank lines between test cases. Proceed to the end of input.

    Output

    For each test cases, output a single line of space-separated integers which are the values of people in the order they stand in the queue.

    Sample Input

    4
    0 77
    1 51
    1 33
    2 69
    4
    0 20523
    1 19243
    1 3890
    0 31492

    Sample Output

    77 33 69 51
    31492 20523 3890 19243

    Hint

    The figure below shows how the Little Cat found out the final order of people in the queue described in the first test case of the sample input.

    先将数据存储起来,然后逆序进行插入操作,如果当前位置已经被占就往后面插

    线段树维护一个 剩余位置个数

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/17 21:18:26
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 200100
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    struct node{
        int l,r,pos,val;//记录还有几个位置可以放
    }nod[maxn*4];
    int pos[maxn],k;
    typedef pair<int,int>pii;
    pii p[maxn];
    
    void push_up(int i){
        nod[i].pos=nod[i<<1].pos+nod[(i<<1)|1].pos;
    }
    void build(int i,int l,int r ){
        nod[i].l=l;
        nod[i].r=r;
        if(nod[i].l==nod[i].r){
            nod[i].pos=1;
            return;
        }
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
        push_up(i);
    }
    void update(int i,int pos,int val){
        if(nod[i].l==nod[i].r){
            nod[i].val=val;
            nod[i].pos=0;
            return ;
        }
        if(pos<nod[i<<1].pos)update(i<<1,pos,val);
        else update((i<<1)|1,pos-nod[i<<1].pos,val);
        push_up(i);
    }
    void quary(int i){//因为要取底层的值所以还要进行一下对底层的询问
        if(nod[i].l==nod[i].r){
            pos[k++]=nod[i].val;
            return ;
        }
        quary(i<<1);
        quary(i<<1|1);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int n;
        while(cin>>n){
            k=0;
            for(int i=1;i<=n;i++){
                scanf("%d%d",&p[i].first,&p[i].second);
            }
            build(1,1,n);
            for(int i=n;i>=1;i--){
                update(1,p[i].first,p[i].second);
            }
            quary(1);
            for(int i=0;i<n-1;i++)
                printf("%d ",pos[i]);
            printf("%d
    ",pos[n-1]);
        }
        return 0;
    }
    View Code

    6.poj 2886

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/22 20:08:11
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 500005
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    int antiprime[] = {1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,
    5040,7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,166320,
    221760,277200,332640,498960,554400};
    //对应的约数个数
    int factor[] = {1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,
    64,72,80,84,90,96,100,108,120,128,144,160,168,180,192,200,216};
    struct Node{
        char name[100];
        int num;
    }c[maxn];
    
    struct node{
        int l,r,sum;
    }nod[maxn*4];
    void push_up(int i){
        nod[i].sum=nod[i<<1].sum+nod[i<<1|1].sum;
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        if(l==r){
            nod[i].sum=1;
            return ;
        }
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
        push_up(i);
    }
    int update(int i,int w){
        int mark;
        if(nod[i].l==nod[i].r){
            nod[i].sum=0;
            return nod[i].l;
        }
        if(w<=nod[i<<1].sum)mark=update(i<<1,w);
        else mark= update(i<<1|1,w-nod[i<<1].sum);
        push_up(i);
        
        return mark;
    }
    bool cmp(int a,int b){
        return a>b;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int t,n,k;
        while(cin>>n>>k){
            for(int i=1;i<=n;i++){
                scanf("%s %d",&c[i].name,&c[i].num);
            }
            build(1,1,n);    
            int cnt=0;
            while(antiprime[cnt]<=n)cnt++;
            cnt--;
            int pos=0;
            c[pos].num=0;
            for(int i=0;i<antiprime[cnt];i++){
                if(c[pos].num>0)k=((k+c[pos].num-2)%nod[1].sum)%nod[1].sum+1;
                else k=((k+c[pos].num-1)%nod[1].sum+nod[1].sum)%nod[1].sum+1;
                pos=update(1,k);
            }
            printf("%s %d
    ",c[pos].name,factor[cnt]);
        }
        return 0;
    }
    View Code

    7.hdu 1698   区间更新

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/23 20:56:20
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 101000
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    struct node{
        int l,r,sum;
        int c;//延迟标记  
        //延迟到下à一次更新或者下一次查询
    }nod[maxn*4];
    void push_up(int i){
        nod[i].sum=nod[i<<1].sum+nod[i<<1|1].sum;
    }
    void push_down(int i){
        if(nod[i].c>0){
            nod[i<<1].c=nod[i<<1|1].c=nod[i].c;
            nod[i<<1].sum=(nod[i<<1].r-nod[i<<1].l+1)*nod[i].c;
            nod[i<<1|1].sum=(nod[i<<1|1].r-nod[i<<1|1].l+1)*nod[i].c;
            nod[i].c=0;
        }
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].c=0;
        if(l==r){
            nod[i].sum=1;
            return ;
        }
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
        push_up(i);
    }
    void update(int i,int l,int r,int x){
        if(nod[i].l==l&&nod[i].r==r){
            nod[i].c=x;
            nod[i].sum=(nod[i].r-nod[i].l+1)*nod[i].c;
            return ;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update(i<<1,l,r,x);
        else if(l>mid)update(i<<1|1,l,r,x);
        else{
            update(i<<1,l,mid,x);
            update(i<<1|1,mid+1,r,x);
        }
        push_up(i);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int t,n,m,cnt=0;
        cin>>t;
        while(t--){
            cin>>n>>m;
            int x,y,z;
            build(1,1,n);
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&x,&y,&z);
                update(1,x,y,z);
            }
            printf("Case %d: The total value of the hook is %d.
    ",++cnt,nod[1].sum);
        }
        return 0;
    }
    View Code

    8.poj3468  区间更新,查询区间和

    A Simple Problem with Integers
    Time Limit: 5000MS   Memory Limit: 131072K
    Total Submissions: 80597   Accepted: 24888
    Case Time Limit: 2000MS

    Description

    You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

    Input

    The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
    The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
    Each of the next Q lines represents an operation.
    "C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of AaAa+1, ... , Ab.

    Output

    You need to answer all Q commands in order. One answer in a line.

    Sample Input

    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    

    Sample Output

    4
    55
    9
    15

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/24 18:28:55
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 111000
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    struct node{
        int l,r;
        ll sum;
        ll c;//延迟标记
    }nod[maxn*4];
    ll a[maxn];
    int j;
    void push_up(int i){
        nod[i].sum=nod[i<<1].sum+nod[i<<1|1].sum;
    }
    void push_down(int i){
        if(nod[i].c){
            nod[i<<1].c+=nod[i].c;
            nod[i<<1|1].c+=nod[i].c;
            nod[i<<1].sum+=(ll)(nod[i<<1].r-nod[i<<1].l+1)*nod[i].c;
            //向下面推一层
            nod[i<<1|1].sum+=(ll)(nod[i<<1|1].r-nod[i<<1|1].l+1)*nod[i].c;
            nod[i].c=0;
        }
    }
    
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].c=0;
        if(l==r){
            nod[i].sum=a[++j];
            return ;
        }
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
        push_up(i);
    }
    void update(int i,int l,int r,ll w){
        if(nod[i].l==l&&nod[i].r==r){
            nod[i].c+=w;
            nod[i].sum+=(r-l+1)*w;//注意
            return ;
        }
        if(nod[i].l==nod[i].r)return ;
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update(i<<1,l,r,w);
        else if(mid<l) update(i<<1|1,l,r,w);
        else{
            update(i<<1,l,mid,w);
            update(i<<1|1,mid+1,r,w);
        }
        push_up(i);
    }
    ll quary(int i,int l,int r){
        if(nod[i].l==l&&nod[i].r==r){
            return nod[i].sum;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        ll ans=0;
        if(r<=mid)ans+=quary(i<<1,l,r);
        else if(l>mid)ans+=quary(i<<1|1,l,r);
        else {
            ans+=quary(i<<1,l,mid);
            ans+=quary(i<<1|1,mid+1,r);
        }
        push_up(i);
        return ans;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int n,q,x,y;
        ll z;
        while(cin>>n>>q){
            for(int i=1;i<=n;i++){
                scanf("%I64d",&a[i]);
            }
            j=0;
            build(1,1,n);
            char s[20];
            for(int i=1;i<=q;i++){
                scanf("%s",s);
                if(s[0]=='Q'){
                    scanf("%d%d",&x,&y);
                    printf("%I64d
    ",quary(1,x,y));
                    
                }
                else{
                    scanf("%d%d%I64d",&x,&y,&z);
                    update(1,x,y,z);
                }
            }
        }
        return 0;
    }
    View Code

    9.poj2528 http://poj.org/problem?id=2528  求没有被完全覆盖的海报数量

    由于数据较大  离散化 区间 染色 注意离散化的姿势

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/25 9:30:35
    File Name     :4.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 105000
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    struct node{
        int l,r;
        int c;//延迟标记
    }nod[maxn*4];
    pair<int,int>a[maxn];
    int mp[10001000];
    int x[maxn*2],vis[maxn];
    bool cmp(int a,int b){
        return a>b;
    }
    void push_down(int i){
        if(nod[i].c){
            nod[i<<1].c=nod[i<<1|1].c=nod[i].c;
            nod[i].c=0;
        }
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].c=0;
        if(l==r)return ;
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
    }
    void update(int i,int l,int r,int w){
        if(nod[i].l==l&&nod[i].r==r){
            nod[i].c=w;
            return ;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update(i<<1,l,r,w);
        else if(l>mid)update(i<<1|1,l,r,w);
        else{
            update(i<<1,l,mid,w);
            update(i<<1|1,mid+1,r,w);
        }
    }
    int quary(int i){
        int num=0;
        if(nod[i].c!=0){
            if(!vis[nod[i].c])vis[nod[i].c]=1,num++;
            //return num;
        }
        if(nod[i].l==nod[i].r)return num;
        num+=quary(i<<1);
        num+=quary(i<<1|1);
    }
    int ans;
    void serch(int i)
    {
        if(nod[i].c!=0)
        {
            if(!vis[nod[i].c])
            {
                vis[nod[i].c]=1,ans++;
            }
            return ;
        }
        if(nod[i].r==nod[i].l)return;
        serch(i<<1);
        serch(i<<1|1);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int n,t;
        cin>>t;
        while(t--){
            scanf("%d",&n);
            int j=0;
            for(int i=1;i<=n;i++){
                scanf("%d%d",&a[i].first,&a[i].second);
                x[++j]=a[i].first;
                x[++j]=a[i].second;
            }
            sort(x+1,x+1+j);
            cle(mp);
            for(int i=1;i<=j;i++){
                if(!mp[x[i]])mp[x[i]]=i;
            }
            build(1,1,j);
            for(int i=1;i<=n;i++){
                //cout<<mp[a[i].first]<<" "<<mp[a[i].second]<<endl;
                update(1,mp[a[i].first],mp[a[i].second],i);
            }
            cle(vis);
            ans=0;
            serch(1);
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    10.poj 3225 http://poj.org/problem?id=3225(难 啊)

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/9/30 18:37:20
    File Name     :poj3225.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 131072
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    struct node{
        int l,r,col,rev;//延迟标记
    }nod[maxn*4];
    char s1[10],s2[20];
    int a[maxn+10];
    
    void push_down(int i){
        if(nod[i].l==nod[i].r)return;
        if(nod[i].col!=-1){// 区间被完全覆盖
            nod[i<<1].col=nod[i<<1|1].col=nod[i].col;
            nod[i].col=-1;
            nod[i].rev=0;
            nod[i<<1].rev=nod[i<<1|1].rev=0;
            //儿子节点也被完全覆盖 因此要抹掉异或操作
        }
        if(nod[i].rev){//区间没有被完全覆盖发
            if(nod[i<<1].col!=-1){//儿子节点被完全覆盖 字节异或
                nod[i<<1].col^=1;
            }
            else nod[i<<1].rev^=1;//否则对rev进行异或
            if(nod[i<<1|1].col!=-1){
                nod[i<<1|1].col^=1;
            }
            else nod[i<<1|1].rev^=1;
            nod[i].rev=0;
        }
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].col=0;
        nod[i].rev=0;
        if(l==r){
            return ;
        }
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
    }/*
    void update(int i,int l,int r,int col){
        if(l>r)return;
        if(nod[i].l==l&&nod[i].r==r){
            if(col==0||col==1){
                nod[i].col=col;
                nod[i].rev=0;
            }
            else{
                if(nod[i].col!=-1)nod[i].col^=1;
                else nod[i].rev^=1;
            }
            return ;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update(i<<1,l,r,col);
        else if(l>mid)update(i<<1|1,l,r,col);
        else {
            update(i<<1,l,mid,col);
            update(i<<1|1,mid+1,r,col);
        }
    }*/
    void update(int v, int l, int r, int col)
    {
        if(l > r) //l > r的区间忽略不计
            return;
        if(nod[v].l == l && nod[v].r == r)
        {
            if(col == 0 || col == 1)
            {
                nod[v].col = col;
                nod[v].rev = 0;
            }
            else
            {
                if(nod[v].col != -1)
                    nod[v].col ^= 1;
                else
                    nod[v].rev ^= 1;
            }
            return;
        }
        push_down(v);
        int mid = (nod[v].l + nod[v].r) >> 1;
        if(r <= mid)
            update(v*2,l,r,col);
        else if(l > mid)
            update(v*2+1,l,r,col);
        else
        {
            update(v*2,l,mid,col);
            update(v*2+1,mid+1,r,col);
        }
    }
    void query(int i){
        if(nod[i].col==1){
            for(int j=nod[i].l;j<=nod[i].r;j++)a[j]=nod[i].col;
            return ;
        }
        if(nod[i].col==0)return ;
        if(nod[i].l==nod[i].r)return ;
        push_down(i);
        query(i<<1);
        query(i<<1|1);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        build(1,0,maxn);
        int l,r,len;
        cle(a);
        while(~scanf("%s %s",s1,s2)){
            l=0,r=0;
            len=strlen(s2);
            int i;
            for(i=1;s2[i]>='0'&&s2[i]<='9';i++){
                l=l*10+s2[i]-'0';
            }
            //puts("uuu");
            i++;
            for(;s2[i]>='0'&&s2[i]<='9';i++)
                r=r*10+s2[i]-'0';
            if(s2[0]=='[')l=l*2;
            else l=l*2+1;
            if(s2[len-1]==']')
                r=r*2;
            else r=r*2-1;
            if(s1[0]=='U')update(1,l,r,1);
            else if(s1[0]=='I'){
                update(1,0,l-1,0);
                update(1,r+1,maxn,0);
            }
            else if(s1[0]=='D'){
                update(1,l,r,0);
            }
            else if(s1[0]=='C'){
                update(1,0,l-1,0);
                update(1,r+1,maxn,0);
                update(1,l,r,2);//取反
            }
              else update(1,l,r,2);//取反
        }
            query(1);
            int flag=0;
            for(int i=0;i<maxn;i++){
                if(a[i]==1&&(i==0||a[i-1]==0))l=i;
                if(a[i]==1&&(i==maxn-1||a[i+1]==0)){
                    //puts("nimie a");
                    if(flag==0)flag=1;
                    else printf(" ");
                    if(l%2)printf("(");
                    else printf("[");
                    printf("%d,",l/2);
                    printf("%d",(i+1)/2);
                    if(i%2)printf(")");
                    else printf("]");
                }
            }
            if(flag==0)
                printf("empty set
    ");
            else printf("
    ");
        return 0;
    }
    View Code

    11.poj 1436 区间染色的变形

    /* ***********************************************
    Author        :pk28
    Created Time  :2015/10/2 12:24:17
    File Name     :poj1436.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 8005
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    struct edge{
        int x,y1,y2;
    }e[maxn+10];
    bool cmp(edge a,edge b){
        return a.x<b.x;
    }
    struct node{
        int l,r,c;
    }nod[maxn*8];
    //染色问题
    /*题目大意:
    如果两条线段相交,则叫做水平可见,给出n条这样的线段,求有多少组的3条线段两两可见
    思路:
    对每条线段的横坐标从小到大排序,然后一边插入,一边统计跟当前要插入的线段是否相交,
    存放到vector中,每当插入新的线段,就会覆盖某些旧的线段,抽象地表示了水平可见,相当
    于每条线段都往左边看,可见是相互的,才能保证不重复不遗漏。插入的时候给每条线段一个颜色,
    来区分不同的线段,相当于区间染色*/
    bool v[8005][8005];
    void push_down(int i){
        if(nod[i].c!=-1){
            nod[i<<1].c=nod[i<<1|1].c=nod[i].c;
            nod[i].c=-1;
        }
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].c=-1;
        if(l==r)return;
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
    }
    void update(int i,int l,int r,int w){//w 代表要染成的颜色
        if(nod[i].l==l&&nod[i].r==r){
            nod[i].c=w;
            return ;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update(i<<1,l,r,w);
        else if(l>mid)update(i<<1|1,l,r,w);
        else{
            update(i<<1,l,mid,w);
            update(i<<1|1,mid+1,r,w);
        }
    }
    void query(int i,int l,int r,int w){
        if(nod[i].c!=-1){
            v[w][nod[i].c]=true;
            return;
        }
        if(nod[i].l==nod[i].r)return ;
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)query(i<<1,l,r,w);
        else if(l>mid)query(i<<1|1,l,r,w);
        else {
            query(i<<1,l,mid,w);
            query(i<<1|1,mid+1,r,w);
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int t;
        cin>>t;
        while(t--){
            int n;
            scanf("%d",&n);
            build(1,0,maxn*2);
            memset(v,false,sizeof v);
    
            for(int i=1;i<=n;i++){
                scanf("%d%d%d",&e[i].y1,&e[i].y2,&e[i].x);
            }
            sort(e+1,e+1+n,cmp);
            for(int i=1;i<=n;i++){
                query(1,e[i].y1<<1,e[i].y2<<1,i);
                update(1,e[i].y1<<1,e[i].y2<<1,i);
            }
            int ans=0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++){
                    if(v[i][j])
                        for(int k=1;k<=n;k++)
                            if(v[i][k]&&v[k][j])ans++;
                }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    12.poj2991 线段树的 向量应用

    /* ***********************************************
    Author        :guanjun
    Created Time  :2015/10/2 20:18:31
    File Name     :poj2991.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 100000+10
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    /*当第i段与第i+1段之间的关节进行旋转时,从第i+1段到第n段都要进行旋转,
     * 类似于成段更新(成段旋转),如果把每个线段看成一个向量的话,末端的
     * 坐标等于所有向量的和。已知某个点的坐标(x,y),求逆时针旋转之后的坐标:
     * x'=xcosa-ysina
     * y'=xsina+ycosak可以用极坐标证明'
     */
    struct node{
        int l,r,c;
        double x,y;
    }nod[maxn*4];
    
    int sum[maxn],j=0;
    int angle[maxn];
    
    void push_up(int i){
        nod[i].x=nod[i<<1].x+nod[i<<1|1].x;
        nod[i].y=nod[i<<1].y+nod[i<<1|1].y;
        //cout<<i<<" "<<nod[1].x<<" "<<nod[1].y<<endl;
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].c=0;
        if(l==r){
            nod[i].y=sum[++j];
            nod[i].x=0;
            return ;
        }
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
        push_up(i);
    }
    void rotate(int i,int d){//d 是度数
        double dd=(d)*4.0*atan(1.0)/180.0;
        double x=nod[i].x*cos(dd)-nod[i].y*sin(dd);
        double y=nod[i].x*sin(dd)+nod[i].y*cos(dd);
        nod[i].x=x;
        nod[i].y=y;
    }
    void push_down(int i){
        if(nod[i].c){
            nod[i<<1].c+=nod[i].c;
            nod[i<<1|1].c+=nod[i].c;
            rotate(i<<1,nod[i].c);
            rotate(i<<1|1,nod[i].c);
            nod[i].c=0;
        }
    }
    void update(int i,int l,int r,int d){
        if(nod[i].l==l&&nod[i].r==r){
            //cout<<l<<" "<<r<<endl;
            nod[i].c+=d;
            rotate(i,d);
            return ;
        }
        if(nod[i].l==nod[i].r)return;
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update(i<<1,l,r,d);
        else if(l>mid)update(i<<1|1,l,r,d);
        else {
            update(i<<1,l,mid,d);
            update(i<<1|1,mid+1,r,d);
        }
        push_up(i);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int t,n;
        int mark=0;
        while(scanf("%d %d",&n,&t)!=EOF){
            if(mark)printf("
    ");
        //    cle(sum);cle(angle);
            j=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&sum[i]);
            }
            build(1,1,n);
            for(int i=1;i<=n;i++)
                angle[i]=180;
            int p,deg;
            while(t--){
                scanf("%d%d",&p,&deg);
                update(1,1+p,n,deg-angle[p]);
                angle[p]=deg;
                printf("%.2lf %.2lf
    ",nod[1].x,nod[1].y);
            }
            mark=1;
        }
        return 0;
    }
    View Code

    13.hdu 3308 线段树区间合并

    /* ***********************************************
    Author        :guanjun
    Created Time  :2015/10/3 16:16:10
    File Name     :hdu3308.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 100050
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    struct node{
        int l,r;
        int mx,lx,rx;
        int dist(){return r-l+1;}
    }nod[maxn*4];
    int a[maxn];
    void push_up(int i){
        nod[i].lx=nod[i<<1].lx+((nod[i<<1].lx==nod[i<<1].dist()&&a[nod[i<<1|1].l]>a[nod[i<<1].r])?nod[i<<1|1].lx:0);
        nod[i].rx=nod[i<<1|1].rx+((nod[i<<1|1].rx==nod[i<<1|1].dist()&&a[nod[i<<1].r]<a[nod[i<<1|1].l])?nod[i<<1].rx:0);
        nod[i].mx=max(max(nod[i<<1].mx,nod[i<<1|1].mx),a[nod[i<<1|1].l]>a[nod[i<<1].r]?(nod[i<<1].rx+nod[i<<1|1].lx):0);
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        if(l==r){
            nod[i].lx=nod[i].rx=nod[i].mx=1;
            return ;
        }
        int mid=(l+r)/2;
        build(i<<1,l,mid);
        build(i<<1|1,mid+1,r);
        push_up(i);
    }
    void update(int i,int pos,int k){
        if(nod[i].l==pos&&nod[i].r==pos){    
            a[pos]=k;
            nod[i].lx=nod[i].rx=nod[i].mx=1;
            return ;
        }
        int mid=(nod[i].l+nod[i].r)/2;
        if(pos<=mid)update(i<<1,pos,k);
        else update(i<<1|1,pos,k);
        push_up(i);
    }
    int query(int i,int l,int r){
        if(nod[i].l==l&&nod[i].r==r){
            return nod[i].mx;
        }
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)return query(i<<1,l,r);
        else if(l>mid)return query(i<<1|1,l,r);
        else{
            int lt=query(i<<1,l,mid);
            int rt=query(i<<1|1,mid+1,r);
            int sum=0;
            if(a[nod[i<<1].r]<a[nod[i<<1|1].l]){
                sum=min(nod[i<<1].rx,mid-l+1)+min(nod[i<<1|1].lx,r-mid);
            }
            return max(sum,max(lt,rt));
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int t,n,m,x,y;
        cin>>t;
        char s[20];
        while(t--){
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++)scanf("%d",&a[i]);
            build(1,0,n-1);
            for(int i=1;i<=m;i++){
                scanf("%s %d %d",s,&x,&y);
                if(s[0]=='Q'){
                    printf("%d
    ",query(1,x,y));
                }
                else{
                    update(1,x,y);
                }
            }
        }
        return 0;
    }
    View Code

    14.hdu 3397 线段树综合操作

    /* ***********************************************
    Author        :guanjun
    Created Time  :2015/10/4 12:58:57
    File Name     :hdu3397.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 100100
    #define cle(a) memset(a,0,sizeof(a))
    #define ls  i<<1
    #define rs  i<<1|1
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    struct node{
        int l,r,c;
        int lx,rx,mx;
        int sum;
        int dist;
    }nod[maxn*4];
    int  a[maxn];
    void push_up(int i){
        nod[i].sum=nod[ls].sum+nod[rs].sum;
        nod[i].lx=nod[ls].lx+((nod[ls].lx==nod[ls].dist?nod[rs].lx:0));
        nod[i].rx=nod[rs].rx+((nod[rs].rx==nod[rs].dist?nod[ls].rx:0));
        int a=max(nod[ls].mx,nod[rs].mx);
        int b=max(nod[i].lx,nod[i].rx);
        nod[i].mx=max(max(a,b),nod[ls].rx+nod[rs].lx);
    }
    void push_down(int i){
        if(nod[i].c!=-1){
            nod[ls].c=nod[rs].c=nod[i].c;
            if(nod[i].c==1){//被1完全覆盖
                nod[ls].sum=nod[ls].dist;//更新1的个数
                nod[rs].sum=nod[rs].dist;
                nod[ls].lx=nod[ls].rx=nod[ls].mx=nod[ls].dist;//更新连续的1的个数
                nod[rs].lx=nod[rs].rx=nod[rs].mx=nod[rs].dist;
            }
            else if(nod[i].c==0){
                nod[ls].sum=0;//更新1的个数
                nod[rs].sum=0;
                nod[ls].lx=nod[ls].rx=nod[ls].mx=0;//更新连续的1的个数
                nod[rs].lx=nod[rs].rx=nod[rs].mx=0;
            }
            nod[i].c=-1;
        }
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].c=-1;
        nod[i].dist=r-l+1;
        if(l==r){
            if(a[l]==1)nod[i].lx=nod[i].rx=nod[i].mx=nod[i].sum=1;
            else nod[i].lx=nod[i].rx=nod[i].mx=nod[i].sum=0;
            return;
        }
        int mid=(l+r)/2;
        build(ls,l,mid);
        build(rs,mid+1,r);
        push_up(i);
    }
    void update1(int i,int l,int r,int w){//对于命令0 1的更新 
        if(nod[i].l==l&&nod[i].r==r){
            nod[i].c=w;
            if(w==1){
                nod[i].sum=nod[i].dist;
                nod[i].lx=nod[i].rx=nod[i].mx=nod[i].dist;
            }
            else{
                nod[i].sum=0;
                nod[i].lx=nod[i].rx=nod[i].mx=0;
            }
            return ;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update1(ls,l,r,w);
        else if(l>mid)update1(rs,l,r,w);
        else{
            update1(ls,l,mid,w);
            update1(rs,mid+1,r,w);
        }
        push_up(i);
    }
    void update2(int i,int l,int r){
        if(nod[i].l==l&&nod[i].r==r&&(nod[i].sum==nod[i].dist||nod[i].sum==0)){
            if(nod[i].sum>0){//全1
                nod[i].sum=0;
                nod[i].lx=nod[i].rx=nod[i].mx=0;
                nod[i].c=0;
            }
            else{
                nod[i].lx=nod[i].rx=nod[i].mx=nod[i].dist;
                nod[i].sum=nod[i].dist;
                nod[i].c=1;
            }
            return ;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update2(ls,l,r);
        else if(l>mid)update2(rs,l,r);
        else{
            update2(ls,l,mid);
            update2(rs,mid+1,r);
        }
        push_up(i);
    }
    int query(int i,int l,int r,int w){
        if(nod[i].l==l&&nod[i].r==r){
            if(w==1)return nod[i].sum;
            else return nod[i].mx;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)return query(ls,l,r,w);
        else if(l>mid)return query(rs,l,r,w);
        else{
            if(w==1)return query(ls,l,mid,w)+query(rs,mid+1,r,w);
            else{
                int tmp=max(query(ls,l,mid,w),query(rs,mid+1,r,w));//100110
                return max(tmp,min(nod[ls].rx,nod[ls].r-l+1)+min(nod[rs].lx,r-nod[rs].l+1));
            }
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int t,n,m;
        cin>>t;
        while(t--){
            scanf("%d%d",&n,&m);
            for(int j=1;j<=n;j++)scanf("%d",&a[j]);
            build(1,1,n);
            int x,y,z;
            for(int j=1;j<=m;j++){
                scanf("%d %d %d",&x,&y,&z);
                y++;z++;
                if(x==0)update1(1,y,z,0);
                else if(x==1)update1(1,y,z,1);
                else if(x==2)update2(1,y,z);
                else if(x==3)printf("%d
    ",query(1,y,z,1));
                else if(x==4)printf("%d
    ",query(1,y,z,0));
            }
        }
        return 0;
    }
    View Code

    15.poj3667  线段树区间和并  注意query的写法

    /* ***********************************************
    Author        :guanjun
    Created Time  :2015/10/8 1:47:02
    File Name     :hdu3667.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 80000    
    #define cle(a) memset(a,0,sizeof(a))
    #define ls i<<1
    #define rs i<<1|1
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    bool cmp(int a,int b){
        return a>b;
    }
    struct node{
        int l,r;
        int lx,rx,mx;//记录最大的连续的空的数量
        int c;
        int len;
    }nod[maxn*4];
    void push_up(int i){
        nod[i].lx=nod[ls].lx+(nod[ls].len==nod[ls].lx?nod[rs].lx:0);
        nod[i].rx=nod[rs].rx+(nod[rs].len==nod[rs].rx?nod[ls].rx:0);
        int x=max(nod[ls].mx,nod[rs].mx);
       // int y=max(nod[i].lx,nod[i].rx);
        nod[i].mx=max(x,nod[ls].rx+nod[rs].lx);
    }
    void push_down(int i){
        if(nod[i].c!=-1){
            nod[ls].c=nod[rs].c=nod[i].c;
            if(nod[i].c==0){
                nod[ls].lx=nod[ls].rx=nod[ls].mx=nod[ls].len;
                nod[rs].lx=nod[rs].rx=nod[rs].mx=nod[rs].len;
            }
            if(nod[i].c==1){
                nod[ls].lx=nod[ls].rx=nod[ls].mx=0;
                nod[rs].lx=nod[rs].rx=nod[rs].mx=0;
            }
            nod[i].c=-1;
        }
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].len=r-l+1;
        nod[i].c=-1;
        if(l==r){
            nod[i].lx=nod[i].rx=nod[i].mx=1;
            return ;
        }
        int mid=(l+r)/2;
        build(ls,l,mid);
        build(rs,mid+1,r);
        push_up(i);
    }
    void update(int i,int l,int r,int w){
        if(nod[i].l==l&&nod[i].r==r){
            nod[i].c=w;
            if(w==1)nod[i].lx=nod[i].rx=nod[i].mx=0;
            else nod[i].lx=nod[i].rx=nod[i].mx=nod[i].len;
            return ;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update(ls,l,r,w);
        else if(l>mid)update(rs,l,r,w);
        else{
            update(ls,l,mid,w);
            update(rs,mid+1,r,w);
        }
        push_up(i);
    }
    int query(int i,int w){
        if(nod[i].len==1)return w==1;
        push_down(i);
        if(nod[ls].mx>=w)return query(ls,w);
        if(nod[ls].rx+nod[rs].lx>=w)return nod[ls].r-nod[ls].rx+1;
        if(nod[rs].mx>=w)return query(rs,w);
        return 0;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int n,m,a,b;
        while(cin>>n>>m){
            build(1,1,n);
            //cout<<nod[1].lx<<endl;
            while(m--){
                scanf("%d%d",&a,&b);
                if(a==1){
                    int t=query(1,b);
                    printf("%d
    ",t);
                    if(t)update(1,t,t+b-1,1);
                    //cout<<nod[1].lx<<endl;
                }
                if(a==2){
                    int c;
                    scanf("%d",&c);
                    update(1,b,b+c-1,0);
                }
            }
        }
        return 0;
    }
    View Code

    16.hdu 2871 线段树的综合操作 基于hdu3367  用vector 存储和删除 已添加的线段

    /* ***********************************************
    Author        :guanjun
    Created Time  :2015/10/9 18:39:18
    File Name     :hdu2871.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 90001
    #define INF 0x3f3f3f3f
    #define maxn 50100
    #define cle(a) memset(a,0,sizeof(a))
    #define ls i<<1
    #define rs i<<1|1
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    struct Node{
        int s,e;
        bool operator <(const Node &a) const{
            return s<a.s;
        }
    };
    vector<Node>block(50100);
    struct node{
        int l,r,c;
        int lx,rx,mx;
        int len;
    }nod[maxn*4];
    
    void push_up(int i){
        nod[i].lx=nod[ls].lx+(nod[ls].lx==nod[ls].len?nod[rs].lx:0);
        nod[i].rx=nod[rs].rx+(nod[rs].rx==nod[rs].len?nod[ls].rx:0);
        int a=max(nod[i].lx,nod[i].rx);
        int b=max(nod[ls].mx,nod[rs].mx);
        nod[i].mx=max(max(a,b),nod[ls].rx+nod[rs].lx);
    }
    void push_down(int i){
        if(nod[i].c!=-1){
            nod[ls].c=nod[rs].c=nod[i].c;
            if(nod[i].c==1){//被覆盖
                nod[ls].lx=nod[ls].rx=nod[ls].mx=0;
                nod[rs].lx=nod[rs].rx=nod[rs].mx=0;
            }
            if(nod[i].c==0){
                nod[ls].lx=nod[ls].rx=nod[ls].mx=nod[ls].len;
                nod[rs].lx=nod[rs].rx=nod[rs].mx=nod[rs].len;
            }
            nod[i].c=-1;
        }
    }
    void build(int i,int l,int r){
        nod[i].l=l;
        nod[i].r=r;
        nod[i].c=-1;
        nod[i].len=r-l+1;
        nod[i].lx=nod[i].rx=nod[i].mx=nod[i].len;
        if(l==r){
            //nod[i].lx=nod[i].rx=nod[i].mx=1;
            return ;
        }
        int mid=(l+r)/2;
        build(ls,l,mid);
        build(rs,mid+1,r);
        //push_up(i);
    }
    void update(int i,int l,int r,int w){//1代表覆盖  0代表清空
        if(nod[i].l==l&&nod[i].r==r){
            if(w==1)nod[i].lx=nod[i].rx=nod[i].mx=0;
            else nod[i].lx=nod[i].rx=nod[i].mx=nod[i].len;
            nod[i].c=w;
            return ;
        }
        push_down(i);
        int mid=(nod[i].l+nod[i].r)/2;
        if(r<=mid)update(ls,l,r,w);
        else if(l>mid)update(rs,l,r,w);
        else{
            update(ls,l,mid,w);
            update(rs,mid+1,r,w);
        }
        push_up(i);
    }
    int query(int i,int w){
        if(nod[i].len==1)return w==1;
        push_down(i);
        if(nod[ls].mx>=w)return query(ls,w);
        if(nod[ls].rx+nod[rs].lx>=w)return nod[ls].r-nod[ls].rx+1;
        if(nod[rs].mx>=w)return query(rs,w);
        return 0;
    }
    char s[100];int a;
    int bs(int a){
        int l=0;
        int r=block.size()-1;
        while(l<=r){
            int mid=(l+r)/2;
            if(block[mid].s<=a)
                l=mid+1;
            else r=mid-1;
        }
        return l-1;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int n,m;
        vector<Node>::iterator it;
        while(scanf("%d%d",&n,&m)!=EOF){
            block.clear();
            build(1,1,n);
            for(int i=1;i<=m;i++){
                scanf("%s",s);
                if(s[0]=='N'){
                    scanf("%d",&a);
                    int t=query(1,a);
                    if(t==0)puts("Reject New");
                    else{
                        printf("New at %d
    ",t);
                        Node pos;pos.s=t,pos.e=t+a-1;
                        if(block.size()==0)block.push_back(pos);
                        else{
                            it=lower_bound(block.begin(),block.end(),pos);
                            block.insert(it,pos);
                        }
                        update(1,t,t+a-1,1);
                    }
                }
                if(s[0]=='F'){
                    scanf("%d",&a);
                    int pos=bs(a);
                    if(a<=block[pos].e&&pos>=0&&pos<block.size()){
                        printf("Free from %d to %d
    ",block[pos].s,block[pos].e);
                        update(1,block[pos].s,block[pos].e,0);
                        block.erase(block.begin()+pos);
                    }
                    else printf("Reject Free
    ");
                }
                if(s[0]=='G'){
                    scanf("%d",&a);
                    if(a>block.size()||a<=0&&block.size()>0)puts("Reject Get");
                    else{
                        printf("Get at %d
    ",block[a-1].s);
                    }
                }
                if(s[0]=='R'){
                    update(1,1,n,0);
                    block.clear();
                    puts("Reset Now");
                }
            }
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    luogu P5494 【模板】线段树分裂
    珂朵莉树(ODT)
    luogu P5787 二分图 /【模板】线段树分治
    线段树
    luogu P1450 [HAOI2008]硬币购物
    树形DP
    luogu P3047 [USACO12FEB]Nearby Cows G
    1069: 向Z同学学习
    1067: 有问题的里程表
    1066: 字符分类统计
  • 原文地址:https://www.cnblogs.com/pk28/p/4888191.html
Copyright © 2011-2022 走看看