[卡空间][可持久化线段树]Couriers LibreOJ2432

给定长度为 n 的正整数序列。
有 m 组查询,每次查询区间 [a,b] 中出现次数严格大于一半的数。
即:出现次数大于等于(b-a+1)/2+1的数。

Input

第一行两个整数 n,m (1 ≤ n,m ≤ 500000),表示序列的长度和询问的个数。

接下来一行 n 个整数 p1, p2, …, pn (1 ≤ pi ≤ n),表示该序列。

接下来 m 行,每行两个整数 a,b (1 ≤ a ≤ b ≤ n),表示查询从第 a 个数到第 b 个数之间(包括两个数本身)出现次数严格大于一半的数,如果没有则输出 0.

Output

输出 m 行,对每个询问,输出一行一个整数,表示出现次数超过一半的数,如果没有则输出 0.

Sample Input

7 5
1 1 3 2 3 4 3
1 3
1 4
3 7
1 7
6 6

Sample Output

1
0
3
0
4

题意: 给出一个长度为n的序列以及m次询问,每次询问区间内出现次数严格大于区间长度一半的数。

分析: 比较明显的主席树题目,和主席树模板一样维护区间内权值出现次数,在查询的时候如果左区间个数大于等于目标次数就递归进左区间,如果右区间个数大于等于目标次数就递归进右区间,如果这两种情况都无法进入就直接返回0,表示无法找到符合题意的数。

这道题目这样就可以解决了,但是由于空间卡的实在是太死了,导致疯狂MLE:

最后加了个离散化水过去了,理论上数据再严格点加离散化也不应该过的......

具体代码如下: 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
using namespace std;

const int N = 5e5+5;
struct node{
	int l, r, num;
}tr[24*N]; 
int n, m, cnt, a[N], rt[N];
vector<int> alls;

int find(int x){
	return lower_bound(alls.begin(), alls.end(), x)-alls.begin()+1;
}

int build(int l, int r){
	int id = ++cnt;
	if(l == r) return id;
	int mid = l+r>>1;
	tr[id].l = build(l, mid);
	tr[id].r = build(mid+1, r);
	return id;
}

int insert(int L, int l, int r, int x){
	int id = ++cnt;
	tr[id] = tr[L];
	tr[id].num++;
	if(l == r) return id;
	int mid = l+r>>1;
	if(x <= mid) tr[id].l = insert(tr[L].l, l, mid, x);
	else tr[id].r = insert(tr[L].r, mid+1, r, x);
	return id;
}

//寻找出现次数大于等于k的数 
int query(int L, int R, int l, int r, int k){
	if(l == r) return l;
	int mid = l+r>>1;
	int num_l = tr[tr[R].l].num-tr[tr[L].l].num;
	int num_r = tr[tr[R].r].num-tr[tr[L].r].num;
	if(num_l >= k) return query(tr[L].l, tr[R].l, l, mid, k);
	if(num_r >= k) return query(tr[L].r, tr[R].r, mid+1, r, k);
	return 0;
}

signed main()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
		alls.push_back(a[i]);
	}
	sort(alls.begin(), alls.end());
	alls.erase(unique(alls.begin(), alls.end()), alls.end());
	rt[0] = build(1, alls.size());
	for(int i = 1; i <= n; i++)
		rt[i] = insert(rt[i-1], 1, alls.size(), find(a[i]));
	for(int i = 1; i <= m; i++){
		int l, r, ans;
		scanf("%d%d", &l, &r);
		ans = query(rt[l-1], rt[r], 1, alls.size(), (r-l+1)/2+1);
		if(!ans) puts("0");
		else printf("%d\n", alls[ans-1]);
	} 
		
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供寄件、取件、查询订单、修改订单、取消订单等功能选项(3)根据用户选择执行相应的操作(4)提供良好的用户交互界面(5)使用面向对象编程思想设计程序结构,包括但不限于订单类、用户类、快递员类等。 下面是一个简单的实现示例: ```python class Order: def __init__(self, order_id, sender, receiver, status): self.order_id = order_id self.sender = sender self.receiver = receiver self.status = status def __str__(self): return f"Order ID: {self.order_id}\nSender: {self.sender}\nReceiver: {self.receiver}\nStatus: {self.status}" class User: def __init__(self, user_id, name, phone): self.user_id = user_id self.name = name self.phone = phone class Courier: def __init__(self, courier_id, name, phone): self.courier_id = courier_id self.name = name self.phone = phone class DeliveryService: def __init__(self): self.orders = [] self.users = [] self.couriers = [] def add_order(self, order): self.orders.append(order) def get_order(self, order_id): for order in self.orders: if order.order_id == order_id: return order return None def update_order(self, order_id, status): order = self.get_order(order_id) if order: order.status = status def remove_order(self, order_id): order = self.get_order(order_id) if order: self.orders.remove(order) def add_user(self, user): self.users.append(user) def add_courier(self, courier): self.couriers.append(courier) def show_main_menu(self): print("Welcome to Guoguo Express!") print("1. Send Package") print("2. Receive Package") print("3. Check Order Status") print("4. Update Order Status") print("5. Cancel Order") print("0. Exit") def send_package(self): sender_name = input("Please enter sender's name: ") sender_phone = input("Please enter sender's phone number: ") receiver_name = input("Please enter receiver's name: ") receiver_phone = input("Please enter receiver's phone number: ") order_id = len(self.orders) + 1 order = Order(order_id, f"{sender_name} ({sender_phone})", f"{receiver_name} ({receiver_phone})", "Submitted") self.add_order(order) print("Package sent successfully.") print(order) def receive_package(self): order_id = int(input("Please enter order ID: ")) order = self.get_order(order_id) if order: order.status = "Received" print("Package received successfully.") print(order) else: print("Order not found.") def check_order_status(self): order_id = int(input("Please enter order ID: ")) order = self.get_order(order_id) if order: print(order) else: print("Order not found.") def update_order_status(self): order_id = int(input("Please enter order ID: ")) order = self.get_order(order_id) if order: status = input("Please enter new status: ") self.update_order(order_id, status) print("Order status updated successfully.") print(order) else: print("Order not found.") def cancel_order(self): order_id = int(input("Please enter order ID: ")) order = self.get_order(order_id) if order: self.remove_order(order_id) print("Order canceled successfully.") else: print("Order not found.") def run(self): while True: self.show_main_menu() choice = input("Please enter your choice: ") if choice == "1": self.send_package() elif choice == "2": self.receive_package() elif choice == "3": self.check_order_status() elif choice == "4": self.update_order_status() elif choice == "5": self.cancel_order() elif choice == "0": print("Thank you for using Guoguo Express!") break else: print("Invalid choice. Please try again.") if __name__ == "__main__": ds = DeliveryService() ds.run() ``` 这个控制台程序使用了面向对象编程思想,包括了订单类、用户类、快递员类等,同时提供了寄件、取件、查询订单、修改订单、取消订单等功能选项,并根据用户选择执行相应的操作。用户交互界面也比较友好。你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值