树状数组--csu 1933
2017-05-25 21:39
351 查看
1933: 购买饮料
小明家门口有一个卖饮料的自动售货机,小明经常在那里买饮料。每种饮料有一个流行度,表示它在市场上流行的程度,为了显示自己的与众不同,小明从来不买流行度大于t的饮料。
售货机上有三种操作:
1 在货架上添加一种流行度为x的饮料,并以j作为该饮料的编号,j表示该饮料是第j个被添加的饮料(j从1开始计数)。
2 编号为x的饮料已售罄。
3 小明尝试买第x流行的饮料。
Input
第一行一个整数t。接下来若干行每行两个整数i,x。1<=i<=3 表示该操作是第i种操作。
输入以只包含一个整数0的一行结束。
0<t,x<=106
Output
对每个i=3的操作:如果小明尝试买的饮料流行度v>t,输出"Sorry.";
如果小明尝试买的饮料流行度v<=t,并且未售罄,输出该饮料的流行度;
如果小明尝试购买的饮料已卖完,输出"Meiyou.".
每个输出占一行。
Sample Input
99 1 100 3 1 1 99 1 99 1 99 2 4 2 2 3 2 0
Sample Output
Sorry. 99
树状数组加二分的模板,首先,树状数组C[i]存储的是A[i-2^k+1]至A[i]的和,通过树状数组我们可以在log(n)时间内轻松求数组的前缀和和子段和,考虑到这种情况,数组的前缀和一定是非递减的,所以可以使用二分,我们只要将拥有的流行度的饮料建成一个树状数组通过求前缀和来确定前面有多少种类饮料,二分时候,假设我们要求第i流行的饮料,最后二分到第一个sum(前缀和)等于第i流行的饮料即可,二分区间为【left,right)左闭右开,所以二分时right=mid。
#include <iostream> #include <stdio.h> #include <string.h> #define siz 1000005 #include <queue> using namespace std; int arr[siz],t,i,inde,SSum; int vis[siz],C[siz],A[siz]; int lowbit(int x){ return x&-x; } void Insert(int index,int x){ A[index]=x;vis[x]++; if(vis[x]<=1){ // cout<<x<<" !!!!!!!!!!!!!!!!!"<<endl; while(x<siz){ C[x]+=1; x+=lowbit(x); } ++SSum; } } int Sum(int index){ int sum=0; while(index>0){ sum+=C[index]; index-=lowbit(index); } return sum; } int erfen(int zx){ int left=1,right=siz; int mid; while(left<right){ mid=(left+right)>>1; // cout<<left<<" "<<right<<" "<<mid<<" "<<Sum(mid)<<" "<<zx<<endl; if(Sum(mid)<zx) left=mid+1; else if(Sum(mid)>=zx) right=mid; } //cout<<Sum(mid)<<"&&"<<mid<<endl; return left; } void New(int x){ int d=A[x]; vis[d]--; } void query(int x){ //cout<<SSum<<"%%%%%%%%%%%%%%%%"<<endl; int zx=SSum-x+1; int ans=erfen(zx); //cout<<ans<<endl; if(ans>t){ // cout<<"Sorry."<<endl; printf("Sorry.\n"); } else{ if(vis[ans]<=0) //cout<<"Meiyou."<<endl; printf("Meiyou.\n"); else printf("%d\n",ans); //cout<<ans<<endl; } } int main() { scanf("%d",&t); inde=0; int x; //right=1; while(1){ scanf("%d",&i); if(!i) break; scanf("%d",&x); if(i==1){ Insert(++inde,x); //++index; } else if(i==2){ New(x); } else{ query(x); } } return 0; }
相关文章推荐
- CSU 1335 高桥和低桥(树状数组)
- csu 1770按钮控制彩灯实验(树状数组)
- CSU-ACM2017暑期训练16-树状数组 C - 按钮控制彩灯实验 CSU - 1770
- CSU - 1551 Longest Increasing Subsequence Again —— 线段树/树状数组 + 前缀和&后缀和
- csu 1335 高桥和低桥(树状数组+二分)
- 【树状数组】CSU 1811 Tree Intersection (2016湖南省第十二届大学生计算机程序设计竞赛)
- CSU-ACM2017暑期训练16-树状数组 B - Stars POJ - 2352
- csu1770: 按钮控制彩灯实验 (树状数组)
- 【树状数组】CSU 1811 Tree Intersection (2016湖南省第十二届大学生计算机程序设计竞赛)
- csu 1770 按钮控制彩灯实验(树状数组区间更新)
- CSU-ACM2017暑期训练16-树状数组 D - 斜率小于0的连线数量 51Nod - 1107
- CSU-ACM2017暑期训练16-树状数组 H - Bubble Sort HDU - 5775
- CSU-ACM2017暑期训练16-树状数组 A - Ultra-QuickSort POJ - 2299
- CSU 4441 Necklace (树状数组/LIS)
- 【扫描线或树状数组】CSU 1335 高桥和低桥
- POJ 3321 AppleTree (树状数组)
- POJ 2299 Ultra-QuickSort(树状数组)
- 树状数组laekov
- 【模板】树状数组 区间修改,区间求和 (模板题:洛谷P3372线段树1)
- 树状数组的学习小结