• [hdu&poj&洛谷] 经典线段树练习题 2017-06-01 08:10 56人阅读 评论(0) 收藏


    1.hdu1166敌兵布阵

    #include<stdio.h>
    #include<string.h>
    #define maxn 50000
    int ans;
    struct node 
    {
        int left,right,sum;
        int mid()
        {
            return (left+right)>>1;
        }
    }tree[maxn*4];
    void btree(int left,int right,int rt)
    {
        tree[rt].left=left;
        tree[rt].right=right;
        if(left==right)
        {
            scanf("%d",&tree[rt].sum);
            return ;
        }
        int mid=tree[rt].mid();
        btree(left,mid,rt<<1);
        btree(mid+1,right,rt<<1|1);
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    void query(int left,int right,int rt,int L,int R)
    {
        if(L<=left&&right<=R)
        {
            ans+=tree[rt].sum;
            return;
        }
        int mid=tree[rt].mid();
        if(R<=mid)
            query(left,mid,rt<<1,L,R);
        else if(L>mid)
            query(mid+1,right,rt<<1|1,L,R);
        else
        {
            query(left,mid,rt<<1,L,R);
            query(mid+1,right,rt<<1|1,L,R);
        }
    }
    void update(int left,int right,int rt,int pos,int add)
    {
        if(left==right)
        {
            tree[rt].sum+=add;
            return;
        }
        int mid=tree[rt].mid();
        if(pos<=mid)
            update(left,mid,rt<<1,pos,add);
        else
            update(mid+1,right,rt<<1|1,pos,add);
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
    }
    int main()
    {
        int t,n,cnt;
        int a,b;
        char str[10];
        cnt=1;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            btree(1,n,1);
            printf("Case %d:
    ",cnt++);
            while(scanf("%s",str))
            {
                if(str[0]=='E')
                    break;
                scanf("%d%d",&a,&b);
                if(str[0]=='Q')
                {
                    ans=0;
                    query(1,n,1,a,b);
                    printf("%d
    ",ans);
                }
                else if(str[0]=='A')
                    update(1,n,1,a,b);
                else 
                    update(1,n,1,a,-b);
            }
        }
        return 0;
    }

    2.hdu 1698 just a hook

    #include <iostream>  
    using namespace std;  
    #define MAX_N 100000  
    struct node  
    {  
        int left;  
        int right;  
        int data;  
        int sum;  
    };  
    node hook[4*MAX_N];  
    void CreateTree(int ii,int a,int b)  
    {  
        hook[ii].left = a;  
        hook[ii].right = b;  
        if(a == b)  
        {  
            hook[ii].data = 1;  
            hook[ii].sum = 1;  
        }  
        else  
        {  
            int mid = (a+b)>>1;  
            CreateTree(ii*2,a,mid);  
            CreateTree(ii*2+1,mid+1,b);  
            hook[ii].data = 0;  
            hook[ii].sum = (hook[ii*2].sum + hook[ii*2+1].sum);  
        }  
    }  
    void updata(int ii,int a,int b,int c)  
    {  
        if(hook[ii].left == a && hook[ii].right == b)  
        {  
            hook[ii].data = c;  
            hook[ii].sum = (b-a+1)*c;  
        }  
        else  
        {  
            if(hook[ii].data > 0)  
            {  
                hook[ii*2].data = hook[ii].data;  
                hook[ii*2].sum = (hook[ii*2].right - hook[ii*2].left+1)*hook[ii*2].data;  
                hook[ii*2+1].data = hook[ii].data;  
                hook[ii*2+1].sum = (hook[ii*2+1].right - hook[ii*2+1].left+1)*hook[ii*2+1].data;  
            }  
            hook[ii].data = 0;
            int mid = (hook[ii].left + hook[ii].right)>>1;  
            if(b <= mid)  
            {  
                updata(ii*2,a,b,c);  
            }  
            else if(a > mid)  
            {  
                updata(ii*2+1,a,b,c);  
            }  
            else  
            {  
                updata(ii*2,a,mid,c);  
                updata(ii*2+1,mid+1,b,c);  
            }  
            hook[ii].sum = hook[ii*2].sum + hook[ii*2+1].sum;  
        }  
    }  
    int main()  
    {  
        int t,n,m,x1,x2,x3;  
        int i;  
        scanf("%d",&t);  
        for(i=1;i<=t;i++)  
        {  
            scanf("%d",&n);  
            CreateTree(1,1,n);  
            scanf("%d",&m);  
            while(m--)  
            {  
                scanf("%d%d%d",&x1,&x2,&x3);  
                updata(1,x1,x2,x3);  
            }  
            printf("Case %d: The total value of the hook is %d./n",i,hook[1].sum);  
        }  
        return 0;  
    }  


    3.hud1754 I hate it

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int w[200010];
    struct node{
    	int left;
    	int right;
    	int sum;
    }a[800080];
    void build(int l,int r,int p){
    	a[p].left=l;a[p].right=r;
    	if(l==r) {	a[p].sum=w[l];return ;}
    	if(l<r){
    		build(l,(l+r)/2,2*p);
    		build((l+r)/2+1,r,2*p+1);
    		a[p].sum=max(a[2*p].sum,a[2*p+1].sum);
    	}
    }
    void update(int x,int p,int d){
    	if(a[p].left==x&&a[p].right==x){
    		a[p].sum=d;return ;
    	}
    	int mid=(a[p].left+a[p].right)/2;
    	if(x<=mid) update(x,2*p,d);
    	else if(x>mid) update(x,2*p+1,d);
    	a[p].sum=max(a[2*p].sum,a[2*p+1].sum);
    }
    int query(int l,int r,int p){
    	if(a[p].left==l&&a[p].right==r)
    		return a[p].sum;
    	int mid=(a[p].left+a[p].right)/2;
    	if(r<=mid) return query(l,r,2*p);
    	else if(l>mid) return query(l,r,2*p+1);
    	else return max(query(l,mid,2*p),query(mid+1,r,2*p+1));
    }
    int main(){
    	int n;int m;
    	while(scanf("%d%d",&n,&m)!=EOF){
    		for(int i=1;i<=n;i++)
    			scanf("%d",&w[i]);
    		build(1,n,1);
    		while(m--){
    	        getchar();
    			int x,y,d;
    			char s;
    			scanf("%c",&s);
    			if(s=='U'){
    				scanf("%d%d",&x,&y);
    				update(x,1,y);
    			}
    			else {
    				scanf("%d%d",&x,&y);
    				printf("%d
    ",query(x,y,1));
    			}
    		}
    	}
    	return 0;
    }
    

    4.hdu 2795Billboard

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int h,w,n;
    struct node{
    	int left;
    	int right;
    	int sum;
    }a[800080];
    void build(int l,int r,int p){
    	a[p].left=l;a[p].right=r;a[p].sum=w;
    	if(l==r) return ;
    	if(l<r){
    		build(l,(l+r)/2,2*p);
    		build((l+r)/2+1,r,2*p+1);
    	}
    }
    void update(int p,int d){
    	if(a[p].left==a[p].right){
    		printf("%d
    ",a[p].left);  
            a[p].sum-=d;  
            return;
    	}
    	if(a[2*p].sum>=d) update(2*p,d);
    	else update(2*p+1,d);
    	a[p].sum=max(a[2*p].sum,a[2*p+1].sum);
    }
    int main(){
    	int x;
    	while(scanf("%d%d%d",&h,&w,&n)!=EOF)  
        {  
            build(1,min(h,n),1);
            for(int i=1;i<=n;i++)  
            {  
                scanf("%d",&x);  
                if(x > a[1].sum)  
                {  
                    printf("-1
    ");  
                }  
                else  
                    update(1,x);  
            }  
        }  
        return 0;  
    }
     
    5.hdu1542 Atlantis(扫描线法) 不是很会

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN=2222;
    #define lson i*2,l,m
    #define rson i*2+1,m+1,r
    #define root 1,1,k-1
    double X[MAXN];
    struct node
    {
        double l,r,h;
        int d;
        node(){}
        node(double a,double b,double c,int d): l(a),r(b),h(c),d(d){}
        bool operator <(const node &b)const
        {
            return h<b.h;
        }
    }nodes[MAXN];
    int cnt[MAXN*4];
    double sum[MAXN*4];
    void PushDown(int i,int l,int r)
    {
        int m=(l+r)/2;
        if(cnt[i]!=-1)
        {
            cnt[i*2]=cnt[i*2+1]=cnt[i];
            sum[i*2]= (cnt[i]?(X[m+1]-X[l]):0) ;
            sum[i*2+1]= (cnt[i]?(X[r+1]-X[m+1]):0) ;
        }
    }
    void PushUp(int i,int l,int r)
    {
        if(cnt[i*2]==-1 || cnt[i*2+1]==-1)
            cnt[i]=-1;
        else if(cnt[i*2] != cnt[i*2+1])
            cnt[i]=-1;
        else
            cnt[i]=cnt[i*2];
        sum[i]=sum[i*2]+sum[i*2+1];
    }
    void build(int i,int l,int r)
    {
        if(l==r)
        {
            cnt[i]=0;
            sum[i]=0.0;
            return ;
        }
        int m=(l+r)/2;
        build(lson);
        build(rson);
        PushUp(i,l,r);
    }
    void update(int ql,int qr,int v,int i,int l,int r)
    {
        if(ql<=l && r<=qr)
        {
            if(cnt[i]!=-1)
            {
                cnt[i]+=v;
                sum[i] = (cnt[i]? (X[r+1]-X[l]):0);
                return ;
            }
        }
        PushDown(i,l,r);
        int m=(l+r)/2;
        if(ql<=m) update(ql,qr,v,lson);
        if(m<qr) update(ql,qr,v,rson);
        PushUp(i,l,r);
    }
    int bin(double key,int n,double d[])
    {
        int l=1,r=n;
        while(r>=l)
        {
            int m=(r+l)/2;
            if(d[m]==key)
                return m;
            else if(d[m]>key)
                r=m-1;
            else
                l=m+1;
        }
        return -1;
    }
    int main()
    {
        int q;
        int kase=0;
        while(scanf("%d",&q)==1&&q)
        {
            int n=0,m=0;
            for(int i=1;i<=q;i++)
            {
                double x1,y1,x2,y2;
                scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
                X[++n]=x1;
                nodes[++m]=node(x1,x2,y1,1);
                X[++n]=x2;
                nodes[++m]=node(x1,x2,y2,-1);
            }
            sort(X+1,X+n+1);
            sort(nodes+1,nodes+m+1);
            int k=1;//共k个不同的x坐标,组成了k-1个不同的区域
            for(int i=2;i<=n;i++)
                if(X[i]!=X[i-1]) X[++k]=X[i];
            build(1,1,k-1);//少了build就WA
            double ret=0.0;//最终面积
            for(int i=1;i<m;i++)
            {
                int l=bin(nodes[i].l,k,X);
                int r=bin(nodes[i].r,k,X)-1;
                if(l<=r) update(l,r,nodes[i].d,root);
                ret += sum[1]*(nodes[i+1].h-nodes[i].h);
            }
            printf("Test case #%d
    Total explored area: %.2lf
    
    ",++kase,ret );
        }
    }
    

    6.poj2481 cows
    #include <stdio.h>  
    #include <string.h>  
    #include <algorithm>  
    using namespace std;  
      
    int n;  
    struct node  
    {  
        int l,r,id;  
    } a[1000000];  
    int sum[1000000],num[1000000];  
    int cmp(node x,node y)
    {  
        if(x.l == y.l)  
            return x.r >y.r;  
        return x.l<y.l;  
    }  
    void init(int i,int l,int r,int x)
    {  
        sum[i]++;  
        if(l == r)  
        {  
            return ;  
        }  
        int mid = (l+r)>>1;  
        if(x<=mid)  
            init(2*i,l,mid,x);  
        else  
            init(2*i+1,mid+1,r,x);  
    }  
      
    int insert(int i,int l,int r,int L,int R)  
    {  
        int ss = 0;  
        if(L<=l && r<=R) 
            return sum[i];  
        int mid = (l+r)>>1;  
        if(L<=mid)  
            ss+=insert(2*i,l,mid,L,R);  
        if(R>mid)  
            ss+=insert(2*i+1,mid+1,r,L,R);  
        return ss;  
    }  
      
    int main()  
    {  
         
        while(scanf("%d",&n)!=EOF)  
        {  
        	if(n==0) return 0;
            for(int i = 1; i<=n; i++)  
            {  
                scanf("%d%d",&a[i].l,&a[i].r);  
                a[i].id = i;  
            }  
            memset(sum,0,sizeof(sum));  
            sort(a+1,a+n+1,cmp);  
            for(int i = 1; i<=n; i++)  
            {  
                if(i!=1 && a[i].l == a[i-1].l && a[i].r == a[i-1].r) 
                    num[a[i].id] = num[a[i-1].id];  
                else  
                    num[a[i].id] = insert(1,1,100001,a[i].r,100001);
                init(1,1,100001,a[i].r);
            }  
            for(int i=1; i<=n; i++)  
                printf("%d ",num[i]);  
            printf("
    ");  
      
        }  
      
        return 0;  
    }  

    7.poj3468 a simple problem with integers

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    int w[200010];
    struct node{
    	int left;
    	int right;
    	ll sum;
    	ll addv;
    }a[800080];
    void build(int l,int r,int p){
    	a[p].left=l;a[p].right=r;
    	if(l==r) {	a[p].sum=w[l];return ;}
    	if(l<r){
    		build(l,(l+r)/2,2*p);
    		build((l+r)/2+1,r,2*p+1);
    		a[p].sum=a[2*p].sum+a[2*p+1].sum;
    	}
    }
    void pushdown(int p){
    	if(a[p].addv!=0){
    		a[2*p].addv+=a[p].addv;
    		a[2*p].sum+=a[p].addv*(a[2*p].right-a[2*p].left+1);
    		a[2*p+1].addv+=a[p].addv;
    		a[2*p+1].sum+=a[p].addv*(a[2*p+1].right-a[2*p+1].left+1);
    		a[p].addv=0;
    	}
    }
    void update(int l,int r,int p,int d){
    	if(a[p].left==l&&a[p].right==r){
    		a[p].sum+=(r-l+1)*d;a[p].addv+=d;return ;
    	}
    	pushdown(p);
    	int mid=(a[p].left+a[p].right)/2;
    	if(r<=mid) update(l,r,2*p,d);
    	else if(l>mid) update(l,r,2*p+1,d);
    	else{
    		update(l,mid,2*p,d);update(mid+1,r,2*p+1,d);
    	}
    	a[p].sum=a[2*p].sum+a[2*p+1].sum;
    }
    ll query(int l,int r,int p){
    	if(a[p].left==l&&a[p].right==r)
    		return a[p].sum;
    	pushdown(p);
    	int mid=(a[p].left+a[p].right)/2;
    	if(r<=mid) return query(l,r,2*p);
    	else if(l>mid) return query(l,r,2*p+1);
    	else return query(l,mid,2*p)+query(mid+1,r,2*p+1);
    }
    int main(){
    	int n;int m;
    	scanf("%d",&n);
    	scanf("%d",&m);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&w[i]);
    	build(1,n,1);
    	while(m--){
    		getchar();
    		int x,y;
    		ll d;
    		char k;
    		scanf("%c",&k);
    		if(k=='C'){
    			scanf("%d%d%lld",&x,&y,&d);
    			update(x,y,1,d);
    		}
    		else {
    			scanf("%d%d",&x,&y);
    			printf("%lld
    ",query(x,y,1));
    		}
    	}
    	return 0;
    }
    

    8.洛谷3373 线段树模板2

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    #define ls 2*p
    #define rs 2*p+1
    using namespace std;
    int n,m,t;
    int w[200010];
    struct node{
    	int left;
    	int right;
    	ll sum;
    	ll mulv;
    	ll addv;
    }a[800080];
    void build(int l,int r,int p){
    	a[p].left=l;a[p].right=r;a[p].mulv=1;
    	if(l==r) {	a[p].sum=w[l];return ;}
    	if(l<r){
    		build(l,(l+r)/2,2*p);
    		build((l+r)/2+1,r,2*p+1);
    		a[p].sum=(a[2*p].sum+a[2*p+1].sum)%t;
    	}
    }
    void pushdown(int p){
    	if(a[p].mulv!=1||a[p].addv!=0){
    		a[ls].addv=(a[ls].addv*a[p].mulv)%t;
    		a[ls].mulv=(a[ls].mulv*a[p].mulv)%t;
    		a[rs].addv=(a[rs].addv*a[p].mulv)%t;
    		a[rs].mulv=(a[rs].mulv*a[p].mulv)%t;
    		a[ls].sum=(a[ls].sum*a[p].mulv)%t;
    		a[rs].sum=(a[rs].sum*a[p].mulv)%t;
    		a[p].mulv=1;
    		a[ls].addv=(a[ls].addv+a[p].addv)%t;
    		a[rs].addv=(a[rs].addv+a[p].addv)%t;
    		a[ls].sum=(a[ls].sum+(a[ls].right-a[ls].left+1)*a[p].addv)%t;
    		a[rs].sum=(a[rs].sum+(a[rs].right-a[rs].left+1)*a[p].addv)%t;
    		a[p].addv=0;
    	}
    }
    void addall(int l,int r,int p,int d){
    	if(a[p].left==l&&a[p].right==r){
            a[p].addv=(a[p].addv+d)%t;
            a[p].sum=(a[p].sum+(r-l+1)*d)%t;
            return;
        }
    	pushdown(p);
    	int mid=(a[p].left+a[p].right)/2;
    	if(r<=mid) addall(l,r,2*p,d);
    	else if(l>mid) addall(l,r,2*p+1,d);
    	else {
    		addall(l,mid,2*p,d);
    		addall(mid+1,r,2*p+1,d);
    	}
    	a[p].sum=(a[ls].sum+a[rs].sum)%t;
    }
    void mulall(int l,int r,int p,int d){
    	if(a[p].left==l&&a[p].right==r){
    		a[p].mulv=(a[p].mulv*d)%t;
    		a[p].addv=(a[p].addv*d)%t;
    		a[p].sum=(a[p].sum*d)%t;
    	}
    	pushdown(p);
    	int mid=(a[p].left+a[p].right)/2;
    	if(r<=mid) mulall(l,r,2*p,d);
    	else if(l>mid) mulall(l,r,2*p+1,d);
    	else {
    		addall(l,mid,2*p,d);
    		addall(mid+1,r,2*p+1,d);
    	}
    	a[p].sum=(a[ls].sum+a[rs].sum)%t;
    }
    ll query(int l,int r,int p){
    	if(a[p].left==l&&a[p].right==r)
    		return a[p].sum%t;
    	pushdown(p);
    	int mid=(a[p].left+a[p].right)/2;
    	if(r<=mid) return query(l,r,2*p)%t;
    	else if(l>mid) return query(l,r,2*p+1)%t;
    	else return query(l,mid,2*p)+query(mid+1,r,2*p+1)%t;
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&t);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&w[i]);
    	build(1,n,1);
    	while(m--){
    		int k,x,y;
    		ll d;
    		scanf("%d",&k);
    		if(k==1){
    			scanf("%d%d%lld",&x,&y,&d);
    			mulall(x,y,1,d);
    		}
    		else if(k==2){
    			scanf("%d%d%lld",&x,&y,&d);
    			addall(x,y,1,d);
    		}
    		else {
    			scanf("%d%d",&x,&y);
    			printf("%lld
    ",query(x,y,1));
    		}
    	}
    	return 0;
    }
    


  • 相关阅读:
    Linux学习1-Xshell连接阿里云ECS服务器
    关于面试总结11-selenium面试题
    Word中如何公式居中标号右对齐
    Visio中如何画面积一样的形状
    Visio整体移动
    Visio中汇总两个箭头
    Matlab中ismember用法
    Visio中插入公式
    Visio中如何让重叠图形都显示
    如何命令行编译Java工程
  • 原文地址:https://www.cnblogs.com/xljxlj/p/7183634.html
Copyright © 2020-2023  润新知