【JZOJ A组】百鸽笼

Description

在这里插入图片描述

Input

从文件 pigeon.in 中读入数据。
输入第一行包含两个正整数 n, m ,分别表示初始鸽笼数与操作个数。
第二行包含 n 个正整数,第 i 个数表示从左往右第 i 个初始鸽笼中鸽子的咕咕能力值 vi 。
接下去 m 行每行表示一个操作。操作输入格式见题面描述。

Output

输出到文件 pigeon.out 中。
输出包含若干行,每行表示一个相应的 3 操作的答案。

Sample Input

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

Sample Output

5
4
6
9

Data Constraint

在这里插入图片描述

题目更正:vi值域小于等于1e9。

思路

把序列倒过来,建一棵线段树即可

代码

#include<cstdio>
#include<iostream>
#include<cstring>
#define maxn 400077
#define inf 1000000000
using namespace std;
int n,m,ans,cnt,k[maxn],v[maxn];
struct T{int v,l,r;}tr[maxn*31];
void add(int &d,int l,int r,int x)
{
	tr[++cnt]=tr[d],tr[d=cnt].v++;
	if (l==r) return;
	int mid=(l+r)>>1;
	if (x<=mid) add(tr[d].l,l,mid,x); else add(tr[d].r,mid+1,r,x);
}
void query(int l,int r,int st,int ed,int x)
{
	if (st==ed) { ans=st; return; }
	int mid=(st+ed)>>1;
	if (x<=tr[tr[l].l].v-tr[tr[r].l].v) query(tr[l].l,tr[r].l,st,mid,x);
	else query(tr[l].r,tr[r].r,mid+1,ed,x-tr[tr[l].l].v+tr[tr[r].l].v);
}
int main()
{
	freopen("pigeon.in","r",stdin),freopen("pigeon.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) scanf("%d",&v[i]);
	for(int i=1; i<=n/2; i++) swap(v[i],v[n-i+1]);
	for(int i=1; i<=n; i++) k[i]=k[i-1],add(k[i],0,inf,v[i]);
	for(int i=1,num,x,l,r; i<=m; i++)
	{
		scanf("%d",&num);
		if (num==1) n--;
		if (num==2) scanf("%d",&x),k[++n]=k[n-1],add(k[n],0,inf,x);
		if (num==3)
		{
			scanf("%d%d%d",&l,&r,&x),swap(l,r);
			l=n-l+1,r=n-r+1,query(k[r],k[l-1],0,inf,x);
			printf("%d\n",ans);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值