zoukankan      html  css  js  c++  java
  • 树状数组求第K小值 (spoj227 Ordering the Soldiers && hdu2852 KiKi's K-Number)

    题目:http://www.spoj.com/problems/ORDERS/ and http://acm.hdu.edu.cn/showproblem.php?

    pid=2852

    题意:spoj227:告诉每一个位置前面有多少个数比当前位置小,求出原序列。

    hdu2852:设计一个容器,支持几种操作:添加/删除元素,求容器中比a大的数中第k小的数是多少。

    分析:两个题思路都是求数组里面的第K小的数。開始一直在找O(N*logN)的方法,后来发现O(N*logN*logN)也是能够过的。。

    两步:和先前的逆序数一样先用树状数组处理好比x小的数有多少个,然后二分~(值是单调的)

    spoj227代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 2e5+6;
    int lowbit[maxn],a[maxn],tree[maxn];
    void GetLowbit()
    {
    	for(int i=1;i<maxn;i++)
    		lowbit[i]=i&-i;
    }
    void update(int x,int v)
    {
    	for(int i=x;i<maxn && i;i+=lowbit[i])
    		tree[i]+=v;
    }
    int query(int x)
    {
    	int ret(0);
    	for(int i=x;i>0;i-=lowbit[i])
    		ret+=tree[i];
    	return ret;
    }
    int Find(int x,int n)
    {
    	int ret=1e9,down=1,mid,up=n,v;
    	while(down<=up)
    	{
    		mid=(down+up)>>1;
    		v=query(mid);
    		if(v>=x)
    		{
    			up=mid-1;
    			if(mid<ret && x==v)
    				ret=mid;
    		}
    		else
    			down=mid+1;
    	}
    	return ret;
    }
    int main()
    {
    	GetLowbit();
    	int ncase,n,x,y,v,i,j;
    	scanf("%d",&ncase);
    	while(ncase--)
    	{
    		scanf("%d",&n);
    		memset(tree,0,sizeof(tree[0])*(n+3));
    		for(i=1;i<=n;i++)
    		{
    			update(i,1);
    			scanf("%d",&a[i]);
    		}
    		for(i=n;i>=1;i--)
    		{
    			a[i]=Find(i-a[i],n);
    			update(a[i],-1);
    		}
    		for(i=1;i<n;i++)
    			printf("%d ",a[i]);
    		printf("%d
    ",a[n]);
    	}
    	return 0;
    }

    hdu2852代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 1e5+6;
    int tree[maxn],cnt[maxn],lowbit[maxn];
    void GetLowbit()
    {
    	for(int i=1;i<maxn;i++)
    		lowbit[i]=i&-i;
    }
    void update(int x,int v)
    {
    	for(int i=x;i<maxn && i;i+=lowbit[i])
    		tree[i]+=v;
    }
    int query(int x)
    {
    	int ret(0);
    	for(int i=x;i>0;i-=lowbit[i])
    		ret+=tree[i];
    	return ret;
    }
    int Find(int a,int k)
    {
    	int down=a+1,mid,up=maxn-1,c=query(a),v,ret=1e9;
    	while(down<=up)
    	{
    		mid=(down+up)>>1;
    		v=query(mid)-c;
    		if(v>=k)
    		{
    			up=mid-1;
    			if(ret>mid)
    				ret=mid;
    		}
    		else
    			down=mid+1;
    	}
    	return ret;
    }
    int main()
    {
    	GetLowbit();
    	int q,a,k,tp,v;
    	while(scanf("%d",&q)!=EOF)
    	{
    		memset(tree,0,sizeof(tree));
    		memset(cnt,0,sizeof(cnt));
    		while(q--)
    		{
    			scanf("%d",&tp);
    			if(tp==0)
    			{
    				scanf("%d",&v);
    				cnt[v]++;
    				update(v,1);
    			}
    			else if(tp==1)
    			{
    				scanf("%d",&v);
    				if(cnt[v]>0)
    				{
    					cnt[v]--;
    					update(v,-1);
    				}
    				else
    					puts("No Elment!");
    			}
    			else
    			{
    				scanf("%d%d",&a,&k);
    				int num=query(maxn-1)-query(a);
    				if(num<k)
    					puts("Not Find!");
    				else
    					printf("%d
    ",Find(a,k));
    			}
    		}
    	}
    	return 0;
    }

  • 相关阅读:
    windows(win10)下的mysql解压版安装
    微信和QQ网页授权登录
    图片前端重绘前端压缩和自动调整旋转
    时间的显示
    magento中文语言包的使用
    div垂直居中(js)
    centOS IP能ping通但是域名ping不通
    python3 使用pyinstaller打包exe 指定虚拟路径模块
    Flask 多app案例
    将excel的资产数据生成二维码图片
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5375490.html
Copyright © 2011-2022 走看看