• 【Codevs1080】线段树练习


    这个是线段树or树状数组裸题

    good

    树状数组 (刚学的O(∩_∩)O嗯!)

    //歪鸡劈
    //don't copy
    //or you'll 滚蛋
    //¥¥¥
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    #ifdef WIN32   
    #define OUT "%I64d"
    #else
    #define OUT "%lld"
    #endif
    #define LL long long 
    #define maxn 100010
    using namespace std;
    int getint()
    {
        int w=0,q=0;char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')q=1,ch=getchar();
        while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
        return q?-w:w;
    }
    int a[maxn],low[maxn],sum[maxn],c[maxn];
    int n,i,m;
    int lowbit(int kk)
    {
        return kk&(~kk+1);//  ||(-kk)&kk
    }
    void Init()
    {
        n=getint();sum[0]=0;
        for(i=1;i<=n;i++)
            a[i]=getint(),low[i]=lowbit(i),sum[i]=sum[i-1]+a[i];
        //low数组小优化
        m=getint();
    }
    void Preparation()
    {
        // 初始化 有两种(First 前缀和O(n) Second plus(这一位)O(nlogn))
        for(i=1;i<=n;i++)
            c[i]=sum[i]-sum[i-low[i]];
    }
    void Plus(int x,int k)
    {
        a[x]+=k;
        while(x<=n){
            c[x]+=k;
            x+=low[x];
        }
    }
    int ans;
    int Src(int x)
    {
        ans=0;
        while(x)
        {
            ans+=c[x];
            x-=low[x];
        }
        return ans;
    }
    int flag,x,k;
    void Work()
    {
        while(m--)
        {
            flag=getint();
            if(flag==1)
            {
                x=getint();k=getint();
                Plus(x,k);
            }else{
                x=getint();k=getint();
                printf("%d
    ",Src(k)-Src(x-1));
            }
        }
    }
    int main()
    {
        freopen("ma.in","r",stdin);
        freopen("ma.out","w",stdout);
        Init();
        Preparation();
        Work();
        return 0;
    }
    View Code

    线段树

    //歪鸡劈
    //don't copy
    //or you'll 滚蛋
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #define maxn 100010
    using namespace std;
    int n,m,i,a[maxn];
    int go,l,r,x,A;
    struct Edge
    {
      int l,r,c,mid,kk;
    }tree[maxn*4];
    int getint()
    {
        int w=0,q=0;char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')q=1,ch=getchar();
        while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
        return q?-w:w;
    }
    void Init()
    {
      n=getint();
      for(i=1;i<=n;i++)a[i]=getint();
      m=getint();
    }
    int Build_tree(int l,int r,int k)
    {
      tree[k].l=l;tree[k].r=r;
      if(l==r){tree[k].c=a[l];return a[l];}
      int mid=(l+r)>>1,kk=k<<1;
      tree[k].mid=mid;tree[k].kk=kk;
      tree[k].c=Build_tree(l,mid,kk)+Build_tree(mid+1,r,kk+1);
      return tree[k].c;
    
    }
    void before()
    {
      Build_tree(1,n,1);
    }
    int find(int l,int r,int k)
    {
      if(l==tree[k].l&&r==tree[k].r)
          return tree[k].c;
      if(r<=tree[k].mid)
        return find(l,r,tree[k].kk);
      else{
        if(l<=tree[k].mid)return find(l,tree[k].mid,tree[k].kk)+find(tree[k].mid+1,r,tree[k].kk+1);
        else return find(l,r,tree[k].kk+1);
      }
      return 0;
    }
    void change(int pos,int up,int k)
    {
      if(tree[k].l==tree[k].r)
        {
          tree[k].c+=up;
          return;
        }
      if(pos<=tree[k].mid)
        {
          change(/*tree[k].l,tree[k].mid,*/pos,up,tree[k].kk);
          tree[k].c+=up;
        }
      else
        {
          change(/*tree[k].mid+1,tree[k].r,*/pos,up,tree[k].kk+1);
          tree[k].c+=up;
        }
    }
    void Work()
    {
      while(m--)
        {
          go=getint();
          go--;
          if(go)//2询问
        {
          l=getint();r=getint();
          printf("%d
    ",find(l,r,1));
        }
          else//1改变
        {
          x=getint();A=getint();
          change(x,A,1);
        }
        }
    }
    int main()
    {
        freopen("yjp.in","r",stdin);
        freopen("yjp.out","w",stdout);
        Init();
        before();
        Work();
        return 0;
    }
    View Code
    > 这是一个gang
    
  • 相关阅读:
    shell脚本之for循环
    shell脚本小集锦
    Java构建指定大小文件
    IntelliJ+Maven+Spring+Tomcat项目搭建(MAC)
    Git下基本命令操作
    Mac下IntelliJ的Git、GitHub配置及使用
    Git下的.DS_Store文件
    Mac下GitHub以及GitHub Desktop使用实战
    idea快捷键
    汉字获取首字符
  • 原文地址:https://www.cnblogs.com/YJinpeng/p/5907210.html
Copyright © 2020-2023  润新知