• 小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
    **********************************************************************/
    


  • 相关阅读:
    2020牛客暑期多校训练营(第五场)D 思维|最长上升子序列
    codeforces-1343E(贪心+BFS)
    2020牛客暑期多校训练营(第三场)C 计算几何
    codeforces-1385E(拓扑排序)
    2020牛客寒假算法基础训练营2
    2020牛客寒假算法基础训练营1
    codeforces-1295D(欧拉函数)
    codeforces-1283D(多源BFS)
    深入理解JVM之JVM内存区域与内存分配
    属性动画详解一(Property Animation)
  • 原文地址:https://www.cnblogs.com/csushl/p/9386548.html
Copyright © 2020-2023  润新知