• hdu 5412 CRB and Queries


    CRB and Queries

    http://acm.hdu.edu.cn/showproblem.php?pid=5412

    Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

    Problem Description
    There are N boys in CodeLand.
    Boy i has his coding skill Ai.
    CRB wants to know who has the suitable coding skill.
    So you should treat the following two types of queries.
    Query 1: 1 l v
    The coding skill of Boy l has changed to v.
    Query 2: 2 l r k
    This is a report query which asks the k-th smallest value of coding skill between Boy l and Boy r(both inclusive).
     
    Input
    There are multiple test cases. 
    The first line contains a single integer N.
    Next line contains N space separated integers A1A2, …, AN, where Ai denotes initial coding skill of Boy i.
    Next line contains a single integer Q representing the number of queries.
    Next Q lines contain queries which can be any of the two types.
    1 ≤ NQ ≤ 105
    1 ≤ Aiv ≤ 109
    1 ≤ l ≤ r ≤ N
    1 ≤ k ≤ r  l + 1

    Output
    For each query of type 2, output a single integer corresponding to the answer in a single line.
     
    Sample Input
    5
    1 2 3 4 5
    3
    2 2 4 2
    1 3 6
    2 2 4 2
     
    Sample Output
    3 4
     题意:询问区间第k值(小),支持修改操作
    整体二分+树状数组
    本题与上题不同处在于这里要多组数据输入
     
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N 100001
    int n,m,tot,t;
    int ans[N*2],a[N],k[N*3];
    int c[N];
    struct node
    {
    	int posx,posy,key,kind,bl,cur;
    }q[N*3],tmp1[N*3],tmp2[N*3];
    int lowbit(int x)
    {
    	return x&(-x);
    }
    void add(int x,int y)
    {
    	while(x<=n)
    	{
    		c[x]+=y;
    		x+=lowbit(x);
    	}
    }
    int sum(int x)
    {
    	int b=0;
    	while(x)
    	{
    		b+=c[x];
    		x-=lowbit(x);
    	}
    	return b;
    }
    void solve(int head,int tail,int l,int r)
    {
    	if(head>tail) return;
    	if(l==r)
    	{
    		for(int i=head;i<=tail;i++) 
    		 if(q[i].kind==3) ans[q[i].bl]=l;
    		return;
    	}
    	int mid=l+r>>1;
    	for(int i=head;i<=tail;i++)
    	{
    		if(q[i].kind==1&&q[i].key<=mid) add(q[i].posx,-1);
    		else if(q[i].kind==2&&q[i].key<=mid) add(q[i].posx,1);
    		else if(q[i].kind==3) k[i]=sum(q[i].posy)-sum(q[i].posx-1);
    	}
    	for(int i=head;i<=tail;i++)
    	{
    		if(q[i].kind==1&&q[i].key<=mid) add(q[i].posx,1);
    		else if(q[i].kind==2&&q[i].key<=mid) add(q[i].posx,-1);
    	}
    	int ll=0,rr=0;
    	for(int i=head;i<=tail;i++)
    	{
    		if(q[i].kind==3)
    		{
    			if(q[i].cur+k[i]>=q[i].key) tmp1[++ll]=q[i];
    			else 
    			{
    				q[i].cur+=k[i];
    				tmp2[++rr]=q[i];
    			}
    		}
    		else
    		{
    			if(q[i].key<=mid) tmp1[++ll]=q[i];
    			else tmp2[++rr]=q[i];
    		}
    	}
    	for(int i=1;i<=ll;i++) q[head+i-1]=tmp1[i];
    	for(int i=1;i<=rr;i++) q[head+ll+i-1]=tmp2[i];
    	solve(head,head+ll-1,l,mid);solve(head+ll,tail,mid+1,r);
    }
    void pre()
    {
    	tot=t=0;
    	memset(c,0,sizeof(c));
    }
    int main()
    {
    	while(scanf("%d",&n)!=EOF)
    	{
    		pre();
    		int x,y,z;
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%d",&x);
    			q[++tot]=(node){i,0,x,2};
    			a[i]=x;
    		}
    		scanf("%d",&m); 
    		int h;
    		for(int i=1;i<=m;i++)
    		{
    			scanf("%d",&h);
    			if(h==2) 
    			{
    				scanf("%d%d%d",&x,&y,&z);
    				q[++tot]=(node){x,y,z,3,++t,0};
    			}
    			else 
    			{
    				scanf("%d%d",&x,&z);
    				q[++tot]=(node){x,0,a[x],1,0,0};
    				q[++tot]=(node){x,0,z,2,0,0};
    				a[x]=z;
    			}
    		}
    		solve(1,tot,0,1e9);
    		for(int i=1;i<=t;i++) printf("%d
    ",ans[i]);
    	}
    
    }
    

      

  • 相关阅读:
    淘女郎相册爬虫(Python编写)
    在 Linux 命令行中使用和执行 PHP 代码
    PHP PhantomJs中文文档(翻译)
    PHP
    PHP
    PHP
    PHP — 用PHP实现一个双向队列
    Redis — CentOS6.4安装Redis以及安装PHP客户端phpredis
    Linux
    Memcache学习笔记
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6550777.html
Copyright © 2020-2023  润新知