列表

详情


NC217863. 速度即转发

描述


BPM=RT


给定正整数 ,和非负整数组成的参数序列 
进行  次操作。

操作包含以下两种:

输入描述


第一行,两个正整数 
第二行, 个非负整数 
以下  行,每行第一个整数  表示操作的类型。

若 ,则接下来有三个整数 ,表示一个查询速度操作。
若 ,则接下来有两个整数 ,表示一个转发操作。


输出描述

对于每个查询操作,一行一个整数,表示答案。若在  内无解,输出 

示例1

输入:

6 5
4 42 40 26 46 6
0 1 5 20
1 6 4
0 2 6 20
0 2 6 114514
0 1 6 0

输出:

36
36
-1
100000

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 785ms, 内存消耗: 233184K, 提交时间: 2021-03-19 22:21:53

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
#define N 100012
#define U 20000012
#define LL long long
int n,m,tot=0,a[N],rt[N],c[U][2],s1[U];LL s[U];
inline void Ins(int &p,int l,int r,int v,int v1)
{
	if(!p)p=++tot;s[p]+=v*v1;s1[p]+=v1;if(l==r)return;int mid=(l+r)>>1;
	(v<=mid)?Ins(c[p][0],l,mid,v,v1):Ins(c[p][1],mid+1,r,v,v1);
}
inline void Add(int x,int v,int v1){for(;x<=n;x+=x&(-x))Ins(rt[x],0,100000,v,v1);}
vector<int>I,D;LL su=0;int sz=0;
int Ask(int l,int r,LL k)
{
	if(l==r)return l;int i,u,mid=(l+r)>>1,o;LL v=su-1ll*(mid+1)*sz;
	for(auto p:I)v+=s[c[p][1]]-1ll*(mid+1)*s1[c[p][1]];for(auto p:D)v-=s[c[p][1]]-1ll*(mid+1)*s1[c[p][1]];
	if(v>=k){for(i=0,u=I.size();i<u;i++)I[i]=c[I[i]][1];for(i=0,u=D.size();i<u;i++)D[i]=c[D[i]][1];return Ask(mid+1,r,k);}
	for(i=0,u=I.size();i<u;i++)o=I[i],su+=s[c[o][1]],sz+=s1[c[o][1]],I[i]=c[o][0];
	for(i=0,u=D.size();i<u;i++)o=D[i],su-=s[c[o][1]],sz-=s1[c[o][1]],D[i]=c[o][0];return Ask(l,mid,k);
}
int main(){
	scanf("%d%d",&n,&m);int i,cm,x,v,l,r,ans;LL K;
	for(i=1;i<=n;i++){scanf("%d",&x);Add(i,x,1);a[i]=x;}
	while(m--)
	{
		scanf("%d",&cm);
		if(cm==0)
		{
			scanf("%d%d%lld",&l,&r,&K);I.clear();D.clear();su=0;sz=0;
			for(;r;r&=(r-1))I.push_back(rt[r]);for(--l;l;l&=(l-1))D.push_back(rt[l]);ans=Ask(0,100000,K);
			if(su<K)printf("-1\n");else printf("%d\n",ans);
		}
		else{scanf("%d%d",&x,&v);Add(x,a[x],-1),Add(x,a[x] = v,1);}
	}return 0;
}

上一题