zoukankan      html  css  js  c++  java
  • codevs 1080 线段树练习

    1080 线段树练习

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
    题目描述 Description

    一行N个方格,开始每个格子里都有一个整数。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N<100000,,提问和修改的总数m<10000条。

    输入描述 Input Description

    输入文件第一行为一个整数N,接下来是n行n个整数,表示格子中原来的整数。接下一个正整数m,再接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。

    输出描述 Output Description

    共m行,每个整数

    样例输入 Sample Input

    6

    3

    4

    1 3 5

    2 1 4

    1 1 9

    2 2 6

    样例输出 Sample Output

    22

    22

    数据范围及提示 Data Size & Hint

    1≤N≤100000, m≤10000 。

    两个代码都是用指针写的。

    代码一:

    //codevs 1080
    
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int n,m;
    int sz[100010];
    struct node 
    {
        int val,l,r;
        node * ch[2];//定义指向node这个结构体的指针 
    }*root=NULL;
    int sv(node * cur)
    {
        return cur?cur->val:0;
    }
    void update(node * cur)
    {
        cur->val=sv(cur->ch[0])+sv(cur->ch[1]);
    }
    void build(node * &cur,int l,int r)/*node * &cur加上取地址符号,可以改变原来实参指针的指向*/
    {
        if(l>r)return ;
        cur=new node;/*为这个新节点分配一个结构体*/
        cur->l=l;cur->r=r;//指定一个区间 
        if(l==r)cur->val=sz[l];/*当前是一个单节点*/
        else 
        {
            int mid=(l+r)/2;
            build(cur->ch[0],l,mid);
            build(cur->ch[1],mid+1,r);
            update(cur);//建立好左右孩子之后,更新当前的点 
        }
    }
    void add(node * cur,int pos,int delta)
    {
        if(cur->l==cur->r)//到了叶节点 
        {
            cur->val+=delta;
            return;
        }
        else
        {
            cur->val+=delta;
            int mid=(cur->l+cur->r)/2//二分查找;
            if(pos<=mid)add(cur->ch[0],pos,delta);
            else add(cur->ch[1],pos,delta);
        }
    }
    int query(node * cur,int lp,int rp)/*node * cur不加取地址符号,因为是求和不用改变原来指针的值*/
    {
        if(lp<=cur->l&&cur->r<=rp)return cur->val;
        else
        {
            int ans=0;
            int mid=(cur->l+cur->r)/2;
            if(lp<=mid)ans+=query(cur->ch[0],lp,rp);
            if(rp>mid)ans+=query(cur->ch[1],lp,rp);
            return ans;
        }
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
            scanf("%d",&sz[i]);
        build(root,1,n);
        cin>>m;
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if(a==1)add(root,b,c);
            else printf("%d
    ",query(root,b,c));
        }
        return 0;
    }
    teacher's

    代码二:

    #include<iostream>
    using namespace std;
    #include<cstdio>
    #define INF 100001
    int sz[INF],n,m,a,b,c;
    struct node
    {
        int l,r,val;
        node *child[2]; 
    }*root=NULL;
    void update(node *cur)
    {
        cur->val=cur->child[0]->val+cur->child[1]->val;
    }
    void build(node* &cur,int l,int r)
    {
        if(l>r) return ;
        cur=new node;
        cur->l=l;cur->r=r;
        if(l==r) 
        {
            cur->val=sz[l];
            cur->child[0]=cur->child[1]=NULL;
        }
        else {
            int mid=(l+r)/2;
            build(cur->child[0],l,mid);
            build(cur->child[1],mid+1,r);
            update(cur);
        }
    }
    void input()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        scanf("%d",&sz[i]);
        
    }
    void add(node* cur,int x,int y)
    {
        if(cur->l==cur->r)
        {
            cur->val+=y;
            return;
        }
        else {
            cur->val+=y;
            int mid=(cur->l+cur->r)/2;
            if(x<=mid) add(cur->child[0],x,y);
            else add(cur->child[1],x,y);
        }
    }
    int sum(node* cur,int l1,int r1)
    {
        if(cur->l>=l1&&cur->r<=r1)
        return cur->val;
        else {
            int ans=0;
            int mid=(cur->l+cur->r)/2;
            if(l1<=mid) ans+=sum(cur->child[0],l1,r1);
            if(r1>mid)  ans+=sum(cur->child[1],l1,r1);
            return ans;
        }
    }
    int main()
    {
        input();
        build(root,1,n);
        scanf("%d",&m);
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(a==1)
            add(root,b,c);
            else printf("%d
    ",sum(root,b,c));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ETL Pentaho Data Integration (Kettle) 插入/更新 问题 etl
    Value Investment
    sqlserver 2008r2 表分区拆分问题
    HTTP与HTTPS的区别与联系
    别人分享的面经
    饥人谷开放接口(教程)
    java内存泄漏
    单例模式
    Maven项目上有小红叉咋办
    Socket通信1.0
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5317487.html
Copyright © 2011-2022 走看看