zoukankan      html  css  js  c++  java
  • 小M的魔术表演

    Description

    小M听说会变魔术的男生最能吸引女生注意啦~所以小M费了九牛二虎之力终于学会了一个魔术:
    首先在桌面上放N张纸片,每张纸片上都写有一个数字。小M每次请女生给出一个数字x,然后划定任意一个区间[L,R],小M就能立马告诉对方这个区间内有多少个数字比x小。
    小M当然是知道答案的啦,但是你呢?

    Input

    第一行为一个数字T(T<=10)表示数据组数
    第二行为两个数字n、m(1<=n,m<=200000)表示序列长度和询问次数
    第三行为n个数字表示原始序列A (0 < A[i] < 1000000000)
    接下来m行,每行三个数字l r x 表示询问[l,r]之间小于x的有几个(1<=l<=r<=n,0<=x<=1000000000)
    保证数据合法

    Output

    输出为m行,第i行表示第i个询问的答案

    Sample Input

    1
    10 3
    2 3 6 9 8 5 4 7 1 1
    1 3 5
    2 8 7
    3 6 4

    Sample Output

    2
    4
    0

    Hint


    Submit Page

    一道可持久化线段树的水体,。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector> 
    #include<algorithm>
    using namespace std;
    const int maxn=2e5+10;
    int a[maxn],root[maxn],T,n,m,l,r,x,cnt; 
    vector<int> v;
    
    struct Node{
    	int l,r,sum;
    } tree[maxn*40];
    
    int getid(int x) { return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
    
    void update(int y,int &x,int l,int r,int k)
    {
    	tree[++cnt]=tree[y],tree[cnt].sum++,x=cnt;
    	if(l==r) return ;
    	int mid=(l+r)>>1;
    	if(k<=mid) update(tree[y].l,tree[x].l,l,mid,k);
    	else update(tree[y].r,tree[x].r,mid+1,r,k);	
    }
    
    int query(int y,int x,int l,int r,int pos)
    {
    	if(l==r) return tree[x].sum-tree[y].sum;
    	int mid=(l+r)>>1;
    	int sum=tree[tree[x].l].sum-tree[tree[y].l].sum;
    	if(pos<=mid) return query(tree[y].l,tree[x].l,l,mid,pos);
    	else return sum+query(tree[y].r,tree[x].r,mid+1,r,pos);
    }
    
    int main()
    {
    	//ios::sync_with_stdio(false);
    	scanf("%d",&T);
    	while(T--)
    	{
    		v.clear();cnt=0;
    		memset(root,0,sizeof root);
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=n;i++) scanf("%d",a+i),v.push_back(a[i]);
    		sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());	
    		for(int i=1;i<=n;i++) update(root[i-1],root[i],1,n,getid(a[i]));
    		for(int i=0;i<m;i++)
    		{
    			scanf("%d%d%d",&l,&r,&x);
    			int temp=getid(x);
    			if(temp==1) printf("0
    ");
    			else if(temp>v.size()) printf("%d
    ",r-l+1);
    			else printf("%d
    ",query(root[l-1],root[r],1,n,temp-1));	
    		}	
    	}
    	return 0;
    }
    /**********************************************************************
    	Problem: 1981
    	User: song_hai_lei
    	Language: C++
    	Result: AC
    	Time:1016 ms
    	Memory:98960 kb
    **********************************************************************/
    


  • 相关阅读:
    JQuery学习
    前端Web APIs 二
    前端Web APIS
    Swift 函数式数据结构
    JAVA 四大域对象总结
    Java 访问 C++ 方法:JavaCPP
    写Java也得了解CPU–CPU缓存
    Servlet使用注解标注监听器(Listener)
    Java使用Fork/Join框架来并行执行任务
    Linux学习之让进程在后台可靠运行的方法详解
  • 原文地址:https://www.cnblogs.com/csushl/p/9386548.html
Copyright © 2011-2022 走看看