Pat1057 树状数组求中位数,这题还有结合二分查找,不然后超时
#include<iostream> #include<cstdio> #include<stack> #include<cstring> using namespace std; #define lowbit(x) x&(-x) #define N 100010 int c[N]; void add(int i,int val) { while(i<N) { c[i]+=val; i+=lowbit(i); } } int getsum(int i) { int sum=0; while(i>0) { sum+=c[i]; i-=lowbit(i); } return sum; } int binsearch() { int l=1,r=100000; int k=getsum(100000); k=(k+1)/2; while(l<r) { int mid=(l+r)>>1; if(getsum(mid)>=k)r=mid; else l=mid+1; } return r; } int main() { char op[20]; int n; stack<int>q; while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); while(!q.empty())q.pop(); while(n--) { scanf("%s",op); if(strcmp(op,"Pop")==0) { if(q.empty()) { printf("Invalid\n"); } else { printf("%d\n",q.top()); add(q.top(),-1); q.pop(); } } else if(strcmp(op,"PeekMedian")==0) { if(q.empty()){ printf("Invalid\n"); } else { printf("%d\n",binsearch()); } } else { int x; scanf("%d",&x); q.push(x); add(x,1); } //for(int i=0;i<10;i++)printf(" ** %d %d\n",i,getsum(i)); } } return 0; }
zcmu1203数转数组求逆序数,数据需要离散化,离散化时注意不要把0放进去,否则会死循环
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int M=50004; int a[M],b[M],c[M]; int Lowbit(int x){ return x&-x; } void Update(int x,int y){ int i; for(i=x;i<M;i+=Lowbit(i)){ c[i]+=y; } } int Sum(int x){ int i,ans=0; for(i=x;i;i-=Lowbit(i)){ ans+=c[i]; } return ans; } int main(){ int n,i,k,m,ans; while(~scanf("%d",&n)){ memset(c,0,sizeof(c)); for(i=1;i<=n;i++){ scanf("%d",a+i); b[i]=a[i]; } sort(b+1,b+1+n); //第一步:排序 m=unique(b+1,b+1+n)-(b+1); //第二部:去重 ans=0; for(i=1;i<=n;i++){ k=lower_bound(b+1,b+1+m,a[i])-(b); //第三步 离散 Update(k,1); ans+=(i-1-Sum(k-1)); } printf("%d\n",ans); } return 0; }
hdu5124 n个线段,问被覆盖最多次的点有几条线段,数据需要离散化
树状数组基础题 离散时注意不要把0 放进去 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define maxn 100010 #define low(x) x&(-x) int n,m; int arr[maxn*2]; struct ss { int l,r; }p[maxn]; int sh[maxn*2];//hash int c[maxn]; void add(int i,int val) { while(i<n+m+1) { c[i]+=val; i+=low(i);//i=0会死循环 } } int getsum(int i) { int ans=0; while(i>0) { ans+=c[i]; i-=low(i); } return ans; } int main() { int T; scanf("%d",&T); while(T--) { memset(c,0,sizeof(c)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&p[i].l,&p[i].r); arr[i*2]=p[i].l; arr[i*2+1]=p[i].r; } sort(arr,arr+2*n);//第一步:排序 m=unique(arr,arr+2*n)-arr;//第二部:去重 for(int i=0;i<n;i++) { int x=lower_bound(arr,arr+m,p[i].l)-arr+1;//第三步 离散 int y=lower_bound(arr,arr+m,p[i].r)-arr+1; add(x,1); add(y+1,-1); } int maxNum=0; for(int i=0;i<n+m+1;i++) { int tmp=getsum(i); if(maxNum<tmp)maxNum=tmp; } printf("%d\n",maxNum); } }