[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;
}


原文地址:https://www.cnblogs.com/xljxlj/p/7183634.html