[hdu&poj&洛谷] 经典线段树练习题

1.hdu1166敌兵布阵

#include
#include
#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:\n",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\n",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   
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
#include
#include
#include
#include
#include
#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(lmid) 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\n",query(x,y,1));
			}
		}
	}
	return 0;
}

4.hdu 2795Billboard

#include
#include
#include
#include
#include
#include
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=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\n");  
            }  
            else  
                update(1,x);  
        }  
    }  
    return 0;  
}
 
5.hdu1542 Atlantis(扫描线法) 不是很会

#include
#include
#include
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=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

6.poj2481 cows
#include   
#include   
#include   
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>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("\n");  
  
    }  
  
    return 0;  
}  

7.poj3468 a simple problem with integers

#include
#include
#include
#include
#include
#include
#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(lmid) 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\n",query(x,y,1));
		}
	}
	return 0;
}

8.洛谷3373 线段树模板2

#include
#include
#include
#include
#include
#include
#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(lmid) 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\n",query(x,y,1));
		}
	}
	return 0;
}


你可能感兴趣的:(hdu,数据结构,洛谷,poj,线段树,树)