zoukankan      html  css  js  c++  java
  • PAT 甲级 1057 Stack(树状数组解法)

    本题有一定的难度,如果用普通的栈和数组搭配去做会超时,后来去网上查了做法,有人说可以用树状数组做。本题大致意思就是给定一个栈,有三种操作,分别是push数入栈、pop出栈和寻找栈中按顺序排列的最中间的数,我们可以用一个树状数组记录每个数字存在的次数,配合二分法,每次去求1到n的和,也就是1到n出现了多少次,直到两个边界相遇,趁着本题也算复习了一下树状数组。树状数组------树状数组详解

    #include <iostream>
    #include <string>
    #include <stack> 
    using namespace std;
    const int maxn=100000; 
    int c[maxn+5];
    
    int update(int i,int k)
    {
    	while(i<=maxn)
    	{
    		c[i]+=k;
    		i+=i&(-i);
    	}
    }
    
    int getsum(int i)
    {
    	int res=0;
    	while(i>0)
    	{
    		res+=c[i];
    		i-=i&(-i);
    	}
    	return res;
    }
    
    stack<int> st; 
    int main()
    {
    	int cnt=0,tmp;
    	int n;
    	cin>>n;
    	string op;
    	for(int i=0;i<n;i++)
    	{
    		
    		cin>>op;
    		if(op=="Pop")
    		{
    			if(cnt==0)
    			{
    				cout<<"Invalid
    ";
    			}
    			else 
    			{
    				tmp=st.top();
    				st.pop();
    				update(tmp,-1);
    				cnt--;
    				cout<<tmp<<endl;
    			}
    		}
    		else if(op=="Push")
    		{
    			int u;
    			cin>>u;
    			st.push(u);
    			update(u,1);
    			cnt++;
    		}
    		else if(op=="PeekMedian") 
    		{
    			if(cnt==0)
    			{
    				cout<<"Invalid
    ";
    				continue;
    			}
    			int l=1,r=maxn,mid,goal;
    			if(cnt%2==0) goal=cnt/2;
    			else goal=(cnt+1)/2;
    			while(l<=r)
    			{
    				mid=(l+r)/2;
    				if(getsum(mid)>=goal)
    				{
    					r=mid-1;
    				}
    				else
    				{
    					l=mid+1;
    				}
    			}
    			cout<<l<<endl;
    		}
    		
    	}
    	return 0;
    }
    
  • 相关阅读:
    介绍我的一位同事的开源RSS阅读器
    开源协议概谈[转载]
    编译错误CS1595
    JAVA和C#,武当和少林之争!
    IBatisNet之获取和操作SQL语句
    Linux能否靠架构取得胜利
    开源CMS Alfresco 1.0 发布
    在asp.net页面上得到Castle容器的实例
    IBatisNet 之 自动生成主关键字
    onvaluechange事件
  • 原文地址:https://www.cnblogs.com/ambition-hhn/p/12788353.html
Copyright © 2011-2022 走看看