您的位置:首页 > 其它

PAT 1017 Stack (30)

2016-07-25 10:50 344 查看

思路

1.蛋疼菊紧,思路什么的理清了,答案还不正确,下回再查好了。

2.其实本来可以用一个数组a[]来记录每个值出现的次数(范围从0 – 10^5的个数),然后统计和就能很方便的求出中值了,但是由于数组太大,这样遍历即使是o(n)也受不了。

3.所以接下来这个树状数组的目的就是为了方便求前n项和,注意这里存的是c[],而不是a[]了,俩者的差别看这篇博客。http://www.cppblog.com/menjitianya/archive/2015/11/02/212171.html

4.多写一点吧,重点1.理解lowbit(),重点2.理解Ci = sum{ A[j] | i - 2^k + 1 <= j <= i }。重点3.理解sum(i)= sum( i - lowbit(i) ) + C[i]。即可以用迭代或者递归的方法求sum了,而且速度很快,这样对于找中值就很方便了。

我出错的一些点

1.原来是i要从pos开始。。。omg,注意哪些要更新。

2.上面那个>=,要不要取=要看下面这个(l,half),显然=value是也是(l,half)这个范围内的。

3.switch要记得加break;

代码

#include<iostream>
#include<vector>
#include<algorithm>
#include<stack>
#include<string>
using namespace std;
//其实本来可以用一个数组a[]来记录每个值出现的次数(范围从0 -- 10^5的个数),然后统计和就能很方便的求出中值了,但是由于数组太大,这样遍历即使是o(n)也受不了
//所以接下来这个树状数组的目的就是为了方便求前n项和,注意这里存的是c[],而不是a[]了,俩者的差别看这篇博客http://www.cppblog.com/menjitianya/archive/2015/11/02/212171.html
struct tree
{
static const int MAXN = 100001;
//不能直接声明
//vector<int> a(MAXN,0);
vector<int> a;
tree() :a(vector<int>(MAXN, 0)){}
int lowbit(int t)
{
return t&(-t);
}
//虽然很多,但是log()下来次数就很低了
//额,下面可以写的更简单
//void add(int pos, int val)
//{
//  //原来是i要从pos开始。。。omg
//  for (int i = pos; i < MAXN; i += lowbit(pos))
//  {
//      if (val == 1)
//          a[i]++;
//      else if (val == -1 && a[i]>0)
//          a[i]--;

//  }
//}
//我上面错在哪?
void add(int t, int d)
{
while (t <= MAXN)
{
a[t] += d;
t += lowbit(t);
}
}
//主要就是利用下面的这个性质
//Ci  =  sum{ A[j] |  i - 2^k + 1 <= j <= i }    (帮助理解:将j的两个端点相减+1 等于2^k),并且左边那边的i-2^k后为0了,即加到左边的那项就可以了
//sum(i)= sum( i - lowbit(i) ) + C[i]
int getsum(int k)
{
//return k ? getsum(k - lowbit(k)) + a[k] : 0;;
int s = 0;
for (int i = k; i; i = i - lowbit(k))
{
s += a[i];
}
return s;
}
//为了方面计算,找中值或者找第几个值都从0开始,这样,例如0,1,2的中值就是2/2=1,就是1,这里是讨论value的取值问题。
int findmedian(int value,int l=0,int h=MAXN-1)//可以先赋初值
{
if (l == h)
return l;
int half = (h + l) / 2;
if (getsum(half) >= value)
{
//上面那个>=,要不要取=要看下面这个(l,half),显然=value是也是(l,half)这个范围内的。
return findmedian(value, l, half);
}
else
{
return findmedian(value, half+1, h);
}
}
/*void show()
{
cout << "trees.a:";
for (int i = 0; i < 10; i++)
{
cout << a[i] << " ";
}
cout << endl;
}*/
};
tree trees;
int main()
{
stack<int> a;
int n; string b;int c;
cin >> n;
while (n--)
{
//cout << "aaa" << endl;
cin >> b;
switch (b[1])
{
case 'o':
if (a.empty())
cout << "Invalid" << endl;
else
{
int d = a.top();
a.pop();
cout << d << endl;
trees.add(d, -1);
}
//switch要记得加break;
/*cout << "o:";
trees.show();*/
break;
case 'e':
if (a.empty())
cout << "Invalid" << endl;
else
{
int mid = (int)(a.size() + 1) / 2;
//cout << "mid:" << mid << endl;;
int d = trees.findmedian(mid);
cout << d<<endl;
}
/*cout << "e:";
trees.show();*/
break;
case 'u':
cin >> c;
a.push(c);
trees.add(c, 1);
/*cout << "u:";
trees.show();*/
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: