Codeforces 1181D. Irrigation

https://codeforces.com/contest/1181/status/D

Misha was interested in water delivery from childhood. That's why his mother sent him to the annual Innovative Olympiad in Irrigation (IOI). Pupils from all Berland compete there demonstrating their skills in watering. It is extremely expensive to host such an olympiad, so after the first nn olympiads the organizers introduced the following rule of the host city selection.

The host cities of the olympiads are selected in the following way. There are mm cities in Berland wishing to host the olympiad, they are numbered from 11 to mm. The host city of each next olympiad is determined as the city that hosted the olympiad the smallest number of times before. If there are several such cities, the city with the smallest index is selected among them.

Misha's mother is interested where the olympiad will be held in some specific years. The only information she knows is the above selection rule and the host cities of the first nn olympiads. Help her and if you succeed, she will ask Misha to avoid flooding your house.

Input

The first line contains three integers nn, mm and qq (1≤n,m,q≤5000001≤n,m,q≤500000) — the number of olympiads before the rule was introduced, the number of cities in Berland wishing to host the olympiad, and the number of years Misha's mother is interested in, respectively.

The next line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤m1≤ai≤m), where aiai denotes the city which hosted the olympiad in the ii-th year. Note that before the rule was introduced the host city was chosen arbitrarily.

Each of the next qq lines contains an integer kiki (n+1≤ki≤1018n+1≤ki≤1018) — the year number Misha's mother is interested in host city in.

Output

Print qq integers. The ii-th of them should be the city the olympiad will be hosted in the year kiki.

Examples

input

Copy

6 4 10
3 1 1 1 2 2
7
8
9
10
11
12
13
14
15
16

output

Copy

4
3
4
2
3
4
1
2
3
4

input

Copy

4 5 4
4 4 5 1
15
9
13
6

output

Copy

5
3
3
3

Note

In the first example Misha's mother is interested in the first 1010 years after the rule was introduced. The host cities these years are 4, 3, 4, 2, 3, 4, 1, 2, 3, 4.

In the second example the host cities after the new city is introduced are 2, 3, 1, 2, 3, 5, 1, 2, 3, 4, 5, 1.

 

离线查询,因为每次要查询第K大编号,所以还要用权值线段树动态的insert编号,并查询。

参考:

https://codeforces.com/blog/entry/67727  

https://blog.csdn.net/qq_39565901/article/details/81782611

https://www.cnblogs.com/wzj-xhjbk/p/11039510.html

https://www.cnblogs.com/ilverene/p/9839660.html

https://codeforces.com/contest/1181/submission/55629074

权值线段树维护数组值的对应信息,普通线段树维护下标的对应信息(一个区间基于值,一个基于下标)。在范围大的时候,用对象写权值线段树在需要的时候再new对象。

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	void work() {
		int m=in.nextInt();
		int n=in.nextInt();
		int q=in.nextInt();
		long[] rec=new long[n+1];
		for(int i=0;i<m;i++) {
			rec[in.nextInt()]++;
		}
		long[][] A=new long[n][2];
		for(int i=0;i<n;i++) {
			A[i]=new long[] {rec[i+1],i+1};
		}
		Arrays.sort(A,new Comparator<long[]>() {
			public int compare(long[] arr1,long[] arr2) {
				return (int)(arr1[0]-arr2[0]);
			}
		});
		long cur=m;
		int[] ret=new int[q];
		long[][] Q=new long[q][2];
		for(int i=0;i<q;i++) {
			Q[i]=new long[]{in.nextLong(),i};
		}
		Arrays.sort(Q,new Comparator<long[]>() {
			public int compare(long[] arr1,long[] arr2) {
				if(arr1[0]<arr2[0])return-1;
				else if(arr1[0]>arr2[0]) {
					return 1;
				}else {
					return 0;
				}
			}
		});
		Node root=new Node(0);
		insert((int)A[0][1],root,1,n);
		for(int i=0,j=0;i<q;i++) {
			long[] query=Q[i];
			long r=query[0]-cur;
			while(j<n-1&&(A[j+1][0]-A[j][0])*(j+1)<r) {
				r-=(A[j+1][0]-A[j][0])*(j+1);
				cur+=(A[j+1][0]-A[j][0])*(j+1);
				insert((int)A[j+1][1],root,1,n);
				j++;
			}
			int v=(int)(r%(j+1));
			if(v==0)v=j+1;
			int t=find(v,root,1,n);//第v大的编号
			ret[(int)query[1]]=t;
		}
		for(int i=0;i<q;i++)out.println(ret[i]);
	}
	
	private int find(int v,Node node,int l,int r) {
		if(l==r)return l;
		int m=(l+r)/2;
		if(node.lNode.cnt>=v) {
			return find(v,node.lNode,l,m);
		}else {
			return find(v-node.lNode.cnt,node.rNode,m+1,r);
		}
	}
	private void insert(int v, Node node, int l, int r) {
		node.cnt++;
		if(l==r)return;
		if(node.lNode==null)node.lNode=new Node(0);
		if(node.rNode==null)node.rNode=new Node(0);
		int m=(l+r)/2;
		if(v<=m) {
			insert(v,node.lNode,l,m);
		}else {
			insert(v,node.rNode,m+1,r);
		}
	}

	class Node{
		Node lNode;
		Node rNode;
		int cnt;
		Node(int c){
			cnt=c;
		}
	}
}



class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next() 
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt() 
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CodeForces - 616D是一个关于找到一个序列中最长的第k好子段的起始位置和结束位置的问题。给定一个长度为n的序列和一个整数k,需要找到一个子段,该子段中不超过k个不同的数字。题目要求输出这个序列最长的第k好子段的起始位置和终止位置。 解决这个问题的方法有两种。第一种方法是使用尺取算法,通过维护一个滑动窗口来记录\[l,r\]中不同数的个数。每次如果这个数小于k,就将r向右移动一位;如果已经大于k,则将l向右移动一位,直到个数不大于k。每次更新完r之后,判断r-l+1是否比已有答案更优来更新答案。这种方法的时间复杂度为O(n)。 第二种方法是使用枚举r和双指针的方法。通过维护一个最小的l,满足\[l,r\]最多只有k种数。使用一个map来判断数的种类。遍历序列,如果当前数字在map中不存在,则将种类数sum加一;如果sum大于k,则将l向右移动一位,直到sum不大于k。每次更新完r之后,判断i-l+1是否大于等于y-x+1来更新答案。这种方法的时间复杂度为O(n)。 以上是两种解决CodeForces - 616D问题的方法。具体的代码实现可以参考引用\[1\]和引用\[2\]中的代码。 #### 引用[.reference_title] - *1* [CodeForces 616 D. Longest k-Good Segment(尺取)](https://blog.csdn.net/V5ZSQ/article/details/50750827)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Codeforces616 D. Longest k-Good Segment(双指针+map)](https://blog.csdn.net/weixin_44178736/article/details/114328999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值