• Sequence II HDU


    Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,,ana1,a2,⋯,anThere are m queries. 

    In the i-th query, you are given two integers lili and riri. Consider the subsequence ali,ali+1,ali+2,,ariali,ali+1,ali+2,⋯,ari. 

    We can denote the positions(the positions according to the original sequence) where an integer appears first in this subsequence as p(i)1,p(i)2,,p(i)kip1(i),p2(i),⋯,pki(i) (in ascending order, i.e.,p(i)1<p(i)2<<p(i)kip1(i)<p2(i)<⋯<pki(i)). 

    Note that kiki is the number of different integers in this subsequence. You should output p(i)ki2p⌈ki2⌉(i)for the i-th query.

    Input

    In the first line of input, there is an integer T (T2T≤2) denoting the number of test cases. 

    Each test case starts with two integers n (n2×105n≤2×105) and m (m2×105m≤2×105). There are n integers in the next line, which indicate the integers in the sequence(i.e., a1,a2,,an,0ai2×105a1,a2,⋯,an,0≤ai≤2×105). 

    There are two integers lili and riri in the following m lines. 

    However, Mr. Frog thought that this problem was too young too simple so he became angry. He modified each query to li,ri(1lin,1rin)li‘,ri‘(1≤li‘≤n,1≤ri‘≤n). As a result, the problem became more exciting. 

    We can denote the answers as ans1,ans2,,ansmans1,ans2,⋯,ansm. Note that for each test case ans0=0ans0=0. 

    You can get the correct input li,rili,ri from what you read (we denote them as li,rili‘,ri‘)by the following formula: 

    li=min{(li+ansi1) mod n+1,(ri+ansi1) mod n+1}li=min{(li‘+ansi−1) mod n+1,(ri‘+ansi−1) mod n+1}


    ri=max{(li+ansi1) mod n+1,(ri+ansi1) mod n+1}ri=max{(li‘+ansi−1) mod n+1,(ri‘+ansi−1) mod n+1}

    Output

    You should output one single line for each test case. 

    For each test case, output one line “Case #x: p1,p2,,pmp1,p2,⋯,pm”, where x is the case number (starting from 1) and p1,p2,,pmp1,p2,⋯,pm is the answer.

    Sample Input

    2
    5 2
    3 3 1 5 4
    2 2
    4 4
    5 2
    2 5 2 1 2
    2 3
    2 4

    Sample Output

    Case #1: 3 3
    Case #2: 3 1
    

     给出n个数,然后 m 个查询,查询对应区间的不同的数的个数 k, 以及第 (k+1)/2 个数的位置。

    正序插入的主席树可以很容易的求出区间内不同数的个数,但是在求第 (k+1)/2 个数的位置时,由于树中有 L 之前的信息,不好直接查询出。

    逆序插入的主席树和正序一样,都可以求出区间内不同数的个数,但在求第 (k+1)/2 个数的时候,没有 L 之前的信息,所以可以把问题转换成求这棵树上第 (k+1)/2 大的位置,就是普通的线段树了。

    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pii        pair<int, int>
    #define  INOPEN     freopen("in.txt", "r", stdin)
    #define  OUTOPEN    freopen("out.txt", "w", stdout)
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 2e5 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
    
    int n, m;
    int cas, tol, T;
    
    struct Node{
    	int l, r;
    	int cnt;
    } node[maxn * 40];
    int a[maxn];
    int rt[maxn];
    int last[maxn];
    
    void init() {
    	tol = 0;
    	mes(rt, 0);
    	mes(last, -1);
    }
    
    void update(int l, int r, int &x, int y, int p, int v) {
    	x = ++tol;
    	node[x] = node[y];
    	node[x].cnt += v;
    	if(l == r)	return ;
    	int mid = l + r >> 1;
    	if(p <= mid)
    		update(l, mid, node[x].l, node[y].l, p, v);
    	else
    		update(mid+1, r, node[x].r, node[y].r, p, v);
    }
    
    int query_num(int l, int r, int pl, int pr, int rt) {
    	if(pl <= l && r <= pr) {
    		return node[rt].cnt;
    	}
    	int mid = l + r >> 1;
    	int ans = 0;
    	if(pl <= mid)
    		ans += query_num(l, mid, pl, pr, node[rt].l);
    	if(pr > mid)
    		ans += query_num(mid+1, r, pl, pr, node[rt].r);
    	return ans;
    }
    
    int query_pos(int l, int r, int x, int k) {
    	if(l == r)	return l;
    	int mid = l + r >> 1;
    	int cnt = node[node[x].l].cnt;
    	if(k <= cnt)
    		return query_pos(l, mid, node[x].l, k);
    	else
    		return query_pos(mid+1, r, node[x].r, k-cnt);
    }
    
    int main() {
    	cas = 1;
    	scanf("%d", &T);
    	while(T--) {
    		init();
    		scanf("%d%d", &n, &m);
    		for(int i=1; i<=n; i++) {
    			scanf("%d", &a[i]);
    		}
    		node[0].cnt = 0;
    		for(int i=n; i>=1; i--) {
    			if(last[a[i]] == -1) {
    				update(1, n, rt[i], rt[i+1], i, 1);
    			} else {
    				int tmp;
    				update(1, n, tmp, rt[i+1], last[a[i]], -1);
    				update(1, n, rt[i], tmp, i, 1);
    			}
    			last[a[i]] = i;
    		}
    		printf("Case #%d:", cas++);
    		int ans = 0;
    		while(m--) {
    			int l, r;
    			scanf("%d%d", &l, &r);
    			int tl = min((l+ans)%n+1, (r+ans)%n+1);
    			int tr = max((l+ans)%n+1, (r+ans)%n+1);
    			int k = query_num(1, n, tl, tr, rt[tl]);
    			k = (k + 1) / 2;
    			ans = query_pos(1, n, rt[tl], k);
    			printf(" %d", ans);
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    hbase master 无法启动
    hbase 集群写入能力优化-预分区、TTL的应用
    TiSpark 初级应用
    ETL-kettle 核心执行逻辑
    大学生兼职赚零花钱正规平台来了,京东旗下产品,专为大学生打造
    中国联通笔试面试历年真题
    2020年教师资格证考试笔试面试历年真题
    贵州大学计算机科学与技术学院历年考研真题
    全国计算机等级考试二级、三级、四级历年真题及答案
    教师资格证考试历年真题——中小学幼儿园笔试面试真题
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/10153443.html
Copyright © 2020-2023  润新知