Zoj 2112 Dynamic Rankings

来源:互联网 发布:怎么做网站优化 编辑:程序博客网 时间:2024/05/20 01:09

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112


分块写的,在1~1000000000里面二分答案,判断<=它的数和K的关系,并且判断它是否出现在数组中。

#include <stdio.h>#include <string.h>#include <vector>#include <math.h>#include <algorithm>using namespace std;#define N 500005#define rep(i,s,t) for(int i=s;i<t;i++)typedef pair<int,int>ii;int t;int n,m;int a[N];int S,cnt;char op[2];int x,y,k;vector<int>v[300];vector<int>:: iterator it1,it2;inline int Count(int x,int y,int tmp){int ans=0;while(x<=y && (x-1)%S!=0){if(tmp>=a[x]) ans++;x++;}while(y>=x && (y-1)%S!=S-1){if(tmp>=a[y]) ans++;y--;}if(x<=y){rep(i,(x-1)/S,(y-1)/S+1){it1=upper_bound(v[i].begin(),v[i].end(),tmp);ans+=it1-v[i].begin();}}return ans;}inline int query(int x,int y,int k){int i=1,j=1000000005;while(i<=j){int mid=(i+(j-i)/2);int num=Count(x,y,mid-1);int num1=Count(x,y,mid);//printf("%d %d %d %d %d\n",num,num1,i,j,mid);if(num<k && num1>num && num1>=k) return mid;if(num1>=k) j=mid-1;else i=mid+1;}}inline void modefiy(int x,int y,int val){int old=val,pos=0;int i=(x-1)/S;int s=v[i].size();while(v[i][pos]<old) pos++;v[i][pos]=y;if(y>old){while(pos<s-1 && v[i][pos]>v[i][pos+1]){swap(v[i][pos],v[i][pos+1]);pos++;}}else{while(pos>0 && v[i][pos] < v[i][pos-1]){swap(v[i][pos],v[i][pos-1]);pos--;}}}int main(){scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);S=(int)(sqrt(n+0.5));cnt=(n/S+(n%S!=0?1:0));rep(i,0,cnt+1) v[i].clear();rep(i,1,n+1){scanf("%d",&a[i]);v[(i-1)/S].push_back(a[i]);}rep(i,0,cnt+1){sort(v[i].begin(),v[i].end());}while(m--){scanf("%s%d%d",op,&x,&y);if(op[0]=='Q'){scanf("%d",&k);printf("%d\n",query(x,y,k));}else{if(a[x]!=y){modefiy(x,y,a[x]);a[x]=y;}/*rep(i,0,cnt+1){int s=v[i].size();rep(j,0,s){printf("%d ",v[i][j]);}printf("\n");}*/}}}return 0;}


0 0
原创粉丝点击