zoukankan      html  css  js  c++  java
  • 线段树练手

    Stars

     HDU - 1541

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=40000;
    int T,n,sum[maxn<<2],x,y,ans[maxn];
    int a,b,c,p,t;
    void pushup(int rt)
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void update(int l,int r,int rt)
    {
        if(l==r){
            t+=sum[rt];
            sum[rt]++;
            return;
        }
        int m=(l+r)>>1;
        if(x<=m)
            update(l,m,rt<<1);
        else
        {
            t+=sum[rt<<1];
            update(m+1,r,rt<<1|1);
        }
        pushup(rt);
    }
    int main()
    {
        while(~scanf("%d",&n))
        {
            memset(sum, 0, sizeof(sum));
            memset(ans, 0, sizeof(ans));
            for(int i=1;i<=n;i++){
                t=0;
                scanf("%d%d",&x,&y);
                update(0,32222,1);
                ans[t]++;
            }
            for(int i=0;i<n;i++)printf("%d
    ",ans[i]);
        }
    }

     敌兵布阵

     HDU - 1166

    #include <bits/stdc++.h>
    
    using namespace std;
    int sum[50000<<2],a[50004];
    void pushup(int i)
    {
        sum[i]=sum[i<<1]+sum[i<<1|1];
        return;
    }
    void build(int rt,int l,int r)
    {
        if(l==r)
        {
            sum[rt]=a[l];
            return;
        }
        int m=(l+r)>>1;
        build(rt<<1,l,m);
        build(rt<<1|1,m+1,r);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            return sum[rt];
        }
        int ANS=0;
        int m=(l+r)>>1;
        if(L<=m)ANS+=query(L,R,l,m,rt<<1);
        if(R>m)ANS+=query(L,R,m+1,r,rt<<1|1);
        return ANS;
    }
    void add(int L,int C,int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]+=C;
            return;
        }
        int m=(l+r)>>1;
        if(L<=m)add(L,C,l,m,rt<<1);
        else add(L,C,m+1,r,rt<<1|1);
        pushup(rt);
        return;
    }
    void sub(int L,int C,int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]-=C;
            return;
        }
        int m=(l+r)/2,ql,rq;
        if(L<=m)sub(L,C,l,m,rt<<1);
        else sub(L,C,m+1,r,rt<<1|1);
        pushup(rt);
        return;
    }
    char s[100];
    int main()
    {
        int T,n;
        cin>>T;
        for(int j=1;j<=T;j++)
        {
            cin>>n;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
            }
            build(1,1,n);
            printf("Case %d:
    ",j);
            while(~scanf("%s",s))
            {
                if(s[0]=='E')
                    break;
                int x,y;
                scanf("%d%d",&x,&y);
                if(s[0]=='Q')
                    //cout<<query(1,n,x,y,1)<<endl;
                    cout<<query(x,y,1,n,1)<<endl;
                else if(s[0]=='A')
                    add(x,y,1,n,1);
                else if(s[0]=='S')
                    sub(x,y,1,n,1);
            }
        }
        return 0;
    }

    Just a Hook

     HDU - 1698 

    我屠夫绝活哥

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 100007  //元素总个数
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    int Sum[maxn<<2],Add[maxn<<2];//Sum求和,Add为懒惰标记
    int A[maxn],n;//存原数组数据下标[1,n]
    
    //PushUp函数更新节点信息 ,这里是求和
    void PushUp(int rt){Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];}
    //Build函数建树
    void Build(int l,int r,int rt){ //l,r表示当前节点区间,rt表示当前节点编号
        if(l==r) {//若到达叶节点
            Sum[rt]=A[l];//储存数组值
            return;
        }
        int m=(l+r)>>1;
        //左右递归
        Build(l,m,rt<<1);
        Build(m+1,r,rt<<1|1);
        //更新信息
        PushUp(rt);
    }
    void Update(int L,int C,int l,int r,int rt){//l,r表示当前节点区间,rt表示当前节点编号
        if(l==r){//到叶节点,修改
            Sum[rt]=C;
            return;
        }
        int m=(l+r)>>1;
        //根据条件判断往左子树调用还是往右
        if(L <= m) Update(L,C,l,m,rt<<1);
        else       Update(L,C,m+1,r,rt<<1|1);
        PushUp(rt);//子节点更新了,所以本节点也需要更新信息
    }
    void PushDown(int rt,int ln,int rn){
        //ln,rn为左子树,右子树的数字数量。
        if(Add[rt]){
            //下推标记
            Add[rt<<1]=Add[rt];
            Add[rt<<1|1]=Add[rt];
            //修改子节点的Sum使之与对应的Add相对应
            Sum[rt<<1]=Add[rt]*ln;
            Sum[rt<<1|1]=Add[rt]*rn;
            //清除本节点标记
            Add[rt]=0;
        }
    }
    
    void Update(int L,int R,int C,int l,int r,int rt){//L,R表示操作区间,l,r表示当前节点区间,rt表示当前节点编号
        if(L <= l && r <= R){//如果本区间完全在操作区间[L,R]以内
            Sum[rt]=C*(r-l+1);//更新数字和,向上保持正确
            Add[rt]=C;//增加Add标记,表示本区间的Sum正确,子区间的Sum仍需要根据Add的值来调整
            return ;
        }
        int m=(l+r)>>1;
        PushDown(rt,m-l+1,r-m);//下推标记
        //这里判断左右子树跟[L,R]有无交集,有交集才递归
        if(L <= m) Update(L,R,C,l,m,rt<<1);
        if(R >  m) Update(L,R,C,m+1,r,rt<<1|1);
        PushUp(rt);//更新本节点信息
    }
    
    int main()
    {
        int T,t1,t2,t3;
        cin>>T;
        for(int j=1;j<=T;j++)
        {
            int n;
            scanf("%d",&n);
            fill(A+1,A+1+n,1);
            memset(Sum,0,sizeof(Sum));
            memset(Add,0,sizeof(Add));
            Build(1,n,1);
            int m;
            cin>>m;
            while(m--)
            {
                scanf("%d%d%d",&t1,&t2,&t3);
                Update(t1,t2,t3,1,n,1);
            }
    //        for(int i=1;i<=n;i++)
    //            cout<<A[i]<<' ';
    //        cout<<endl;
            printf("Case %d: The total value of the hook is %d.
    ",j,Sum[1]);
        }
    }

    Color the ball

     HDU - 1556 

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=120000;
    int a[maxn],add[maxn<<2],sum[maxn<<2],x,y,n;
    void up(int rt)
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void pushdown(int rt,int ln,int rn)
    {
        if(add[rt]){
            add[rt<<1]+=add[rt];
            add[rt<<1|1]+=add[rt];
            sum[rt<<1]+=add[rt]*ln;
            sum[rt<<1|1]+=add[rt]*rn;
            add[rt]=0;
        }
    }
    
    void update(int L,int R,int C,int l,int r,int rt)
    {
        if(L<=l&&r<=R){
            sum[rt]+=C*(r-l+1);
            add[rt]+=C;
            return;
        }
        int m=(l+r)>>1;
        pushdown(rt,m-l+1,r-m);
        if(L<=m)update(L,R,C,l,m,rt<<1);
        if(R>m)update(L,R,C,m+1,r,rt<<1|1);
        up(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R){
            return sum[rt];
        }
        int m=(l+r)>>1;
        pushdown(rt,m-l+1,r-m);
        int ans=0;
        if(L<=m)ans+=query(L,R,l,m,rt<<1);
        if(R>m)ans+=query(L,R,m+1,r,rt<<1|1);
        return ans;
    }
    int main()
    {
        int T;
        while(~scanf("%d",&T)&&T)
        {
            memset(add,0,sizeof(add));
            memset(sum,0,sizeof(sum));
            for(int i=1;i<=T;i++){
                scanf("%d%d",&x,&y);
                update(x,y,1,1,T,1);
            }
            for(int i=1;i<T;i++){
                cout<<query(i,i,1,T,1)<<' ';
            }
            cout<<query(T,T,1,T,1);
            cout<<endl;
        }
    }

     

  • 相关阅读:
    总有段迷惑的人生
    codepage的重要性【转】
    开通博客
    js 正则常用方法
    关于小程序scrollview组件添加enableflex后布局失效的解决方案
    关于小程序使用async/await报错regeneratorRuntime is not defined的解决方案
    IE6中,一个Button同时打开两个下载窗口,并且可以自动关闭
    Create User
    Oracle: import tables use .dmp file in PL/SQL Developer
    VS在进行调试时,不能调试的原因列举如下
  • 原文地址:https://www.cnblogs.com/ilikeeatfish/p/12990639.html
Copyright © 2011-2022 走看看