ZOJ2112-Dynamic Rankings(树状数组套主席树)

来源:互联网 发布:松下plc编程手册 编辑:程序博客网 时间:2024/06/06 01:48

Dynamic Rankings

Time Limit: 10 Seconds Memory Limit: 32768 KB

The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1], a[2], …, a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], …, a[j]? (For some i<=j, 0< k<=j+1-i that you have given to it). More powerful, you can even change the value of some a[i], and continue to query, all the same.

Your task is to write a program for this computer, which

  • Reads N numbers from the input (1 <= N <= 50,000)

  • Processes M instructions of the input (1 <= M <= 10,000). These instructions include querying the k-th smallest number of a[i], a[i+1], …, a[j] and change some a[i] to t.

Input

The first line of the input is a single number X (0 < X <= 4), the number of the test cases of the input. Then X blocks each represent a single test case.

The first line of each block contains two integers N and M, representing N numbers and M instruction. It is followed by N lines. The (i+1)-th line represents the number a[i]. Then M lines that is in the following format

Q i j k or
C i t

It represents to query the k-th number of a[i], a[i+1], …, a[j] and change some a[i] to t, respectively. It is guaranteed that at any time of the operation. Any number a[i] is a non-negative integer that is less than 1,000,000,000.

There’re NO breakline between two continuous test cases.

Output

For each querying operation, output one integer to represent the result. (i.e. the k-th smallest number of a[i], a[i+1],…, a[j])

There’re NO breakline between two continuous test cases.

Sample Input

2
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

Sample Output

3
6
3
6

题目大意:动态第k大
解题思路:树状数组套主席树

#include<iostream>#include<cstdio>#include<string>#include<cmath>#include<vector>#include<map>#include<set>#include<queue>#include<algorithm>#include<cstring>using namespace std;typedef long long LL;const int INF=0x3f3f3f3f;const int MAXN=6e4+100;const int M=MAXN*40;int n,q,m,tot;int a[MAXN],t[MAXN];int T[MAXN],lson[M],rson[M],c[M];int S[MAXN];struct Query{  int kind;  int l,r,k;}query[10005];void inithash(int k){  sort(t,t+k);  m=unique(t,t+k)-t;}int Hash(int x){  return lower_bound(t,t+m,x)-t;}int build(int l,int r){  int root=tot++;  c[root]=0;  if(l!=r)  {    int mid=(l+r)/2;    lson[root]=build(l,mid);    rson[root]=build(mid+1,r);  }  return root;}int Insert(int root,int pos,int val){  int newroot=tot++,tmp=newroot;  int l=0,r=m-1;  c[newroot]=c[root]+val;  while(l<r)  {    int mid=(l+r)>>1;    if(pos<=mid)    {      lson[newroot]=tot++;      rson[newroot]=rson[root];      newroot=lson[newroot];      root=lson[root];      r=mid;    }else    {      rson[newroot]=tot++;      lson[newroot]=lson[root];      newroot=rson[newroot];      root=rson[root];      l=mid+1;    }    c[newroot]=c[root]+val;  }  return tmp;}int lowbit(int x){  return x&(-x);}int use[MAXN];void add(int x,int pos,int val){  while(x<=n)  {    S[x]=Insert(S[x],pos,val);    x+=lowbit(x);  }}int sum(int x){  int ret=0;  while(x>0)  {    ret+=c[lson[use[x]]];    x-=lowbit(x);  }  return ret;}int Query(int left,int right,int k){  int leftroot=T[left-1];  int rightroot=T[right];  int l=0,r=m-1;  for(int i=left-1;i;i-=lowbit(i)) use[i]=S[i];  for(int i=right;i;i-=lowbit(i))  use[i]=S[i];  while(l<r)  {    int mid=(l+r)/2;    int tmp=sum(right)-sum(left-1)+c[lson[rightroot]]-c[lson[leftroot]];    if(tmp>=k)    {      r=mid;      for(int i=left-1;i;i-=lowbit(i)) use[i]=lson[use[i]];      for(int i=right;i;i-=lowbit(i))  use[i]=lson[use[i]];      leftroot=lson[leftroot];      rightroot=lson[rightroot];    }else    {      l=mid+1;      k-=tmp;      for(int i=left-1;i;i-=lowbit(i)) use[i]=rson[use[i]];      for(int i=right;i;i-=lowbit(i)) use[i]=rson[use[i]];      leftroot=rson[leftroot];      rightroot=rson[rightroot];    }  }  return l;}void Modify(int x,int p,int d){  while(x<=n)  {    S[x]=Insert(S[x],p,d);    x+=lowbit(x);  }}int main(){  int cas;  scanf("%d",&cas );  while(cas--)  {    scanf("%d%d",&n,&q );    tot=0;    m=0;    for(int i=1;i<=n;i++)    {      scanf("%d",&a[i] );      t[m++]=a[i];    }    char op[10];    for(int i=0;i<q;i++)    {      scanf("%s",op);      if(op[0]=='Q')      {        query[i].kind=0;        scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].k );      }else      {        query[i].kind=1;        scanf("%d%d",&query[i].l,&query[i].r );        t[m++]=query[i].r;      }    }    inithash(m);    T[0]=build(0,m-1);    for(int i=1;i<=n;i++)  T[i]=Insert(T[i-1],Hash(a[i]),1);    for(int i=1;i<=n;i++)  S[i]=T[0];    for(int i=0;i<q;i++)    {      if(query[i].kind==0)          printf("%d\n", t[Query(query[i].l,query[i].r,query[i].k)]);      else      {        Modify(query[i].l,Hash(a[query[i].l]),-1);        Modify(query[i].l,Hash(query[i].r),1);        a[query[i].l]=query[i].r;      }    }  }}/*25 33 2 1 4 7Q 1 4 3C 2 6Q 2 5 35 33 2 1 4 7Q 1 4 3C 2 6Q 2 5 33636*/
阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩张牙齿会发烧怎么办 对节白蜡叶子干了怎么办 刷机字库坏了怎么办 魅蓝返回键失灵怎么办 牙蛀严重且牙根松动怎么办 蛀牙伤到神经了怎么办 给客户发错邮件怎么办外贸 cf没有枪声和脚步声怎么办 穿越火线fps太低怎么办 win10玩cf没有声音怎么办 儿子死了欠的钱怎么办 儿子欠银行的钱怎么办 惹了社会上的混混怎么办 我是五年级惹上混混怎么办 孩子挨欺负家长怎么办幼儿园 孩子被同学欺负不敢上学怎么办 孩子被欺负不敢还手怎么办 2个月的婴儿内热怎么办 孩子把别人打了怎么办 学生在学校被打怎么办 妈和老丈人搞外遇怎么办? 丈人住在双方出资房中怎么办 金木水火土缺水怎么办? 练太极注意不集中怎么办 白色裙子被染色了怎么办 两边的头发向外翘怎么办 感冒的前兆来了怎么办 压腿把筋拉伤了怎么办 压腿压不下去了怎么办 床的气压杆坏了怎么办 床打开压不下去怎么办 裤子大了怎么办小窍门 小孩不准守课堂纪律怎么办 学生在学校体育课受伤怎么办 手指被篮球砸肿了怎么办 眼睛被篮球砸了怎么办 宝宝被篮球砸了怎么办 手被篮球砸肿了怎么办 上体育课时脚不慎扭伤怎么办 孩子受伤没有参加考试怎么办 如果我想离婚对方不愿意怎么办