zoukankan      html  css  js  c++  java
  • poj2828线段树点修改,区间和

    链接:http://poj.org/problem?id=2828

    题意:n个人排队,每个人有一个权值,给出他们插队的位置,求最后的顺序,按顺序输出权值。

    思路:看到这题目,我想这货和线段树什么关系啊,这货怎么能用线段树来做呢。诶,大千世界无奇不有,线段树就是这么的神奇,叹叹!!!闲话少说,走起。

    逆着想,最后一个人插队后, 他的位置就是确定了下来的。倒数第二个人插的话,位置在最后一个的前面,最后一个对他无影响,位置在最后一个后面,则最后一个对他有影响,他必须往后移一位。

    线段树叶子节点保存的是这个位置上的空位数,初始化为1,如果这个位置上有了一个数,那么减一。但是我不明白在查找的时候,为什么用当前人要插入的位置和空位数进行比较,这个位置可以理解为空位数么???求指点。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    const int maxn=200005;
    int sum[maxn<<2];
    int ans[maxn],pos[maxn],val[maxn];
    
    void PushUP(int rt)
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]=1;
            return;
        }
        int m=(l+r)/2;
        build(lson);
        build(rson);
        PushUP(rt);
    }
    void query(int p,int v,int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]-=1;
            ans[r]=v;
            return;
        }
        int m=(l+r)/2;
        if(p<=sum[rt<<1]) query(p,v,lson);//不明白
        else query(p-sum[rt<<1],v,rson);
        PushUP(rt);
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            build(1,n,1);
            for(int i=0;i<n;i++)
                scanf("%d%d",&pos[i],&val[i]);
    
            for(int i=n-1;i>=0;i--)
                query(pos[i]+1,val[i],1,n,1);
            for(int i=1;i<=n;i++)
                printf("%d ",ans[i]);
            printf("
    ");
        }
        return 0;
    }
    View Code

    这题也可以用树状数组写,后面再贴上来。

  • 相关阅读:
    ICommand接口
    Binding自动侦听
    WPF比较两个随机数大小写,利用MVVM思想实现
    从一个ListBox中的元素点击导入另一个ListBox元素中
    利用FluidMoveBehavior制作出手机通讯录平滑的效果
    从零开始学习Gradle之三---多项目构建
    用Gradle 构建你的android程序
    iPhone/iPad调整事件递交
    iOS8-Sampler
    iOS8-Sampler
  • 原文地址:https://www.cnblogs.com/54zyq/p/3273349.html
Copyright © 2011-2022 走看看