列表

详情


NC222906. 下克上の天邪鬼

描述

更好的阅读体验:

链接:https://pan.baidu.com/s/1o4smgWB19XF7_N_0SJ1R9Q ,提取码:dkq4 。



天邪鬼是一种性格扭曲的妖怪。而作为幻想乡的不稳定分子的鬼人正邪,一天到晚脑子里总想着和其他人相反的事情。她天天想着把幻想乡整个翻转过来。

作为看热闹不嫌事大的天邪鬼,正邪非常喜欢看别的妖怪「下克上」。也就是更为弱小(实力上或者是地位上)的妖怪,战胜比他更强的妖怪。正邪拥有让任何事物都翻转过来程度的能力,因此下克上往往都是她主导的。

正邪选出了幻想乡的若干个妖精,希望在其中制造出「下克上」。一次「下克上」的精彩程度,就是两只妖精的能力之和。但是正邪的能力有限,如果两只妖怪实力相差悬殊,那就不大可能达成下克上了。又因为幻想乡的妖精实在是太多了,正邪计算不出怎么策划这场「下克上」。

于是正邪找到了你,希望你根据她的询问,分别找出一对妖精,使得「下克上」的程度最精彩。



正邪选中了幻想乡的 个妖精作为她的考虑对象,并按照次序排成了一列。妖精从左往右编号为 。每个妖精的实力可以用一个正整数 a_i 表示。

正邪一共会发起  次询问,每次给出两个区间 。你需要选择一对妖精 ,满足妖精 在区间 内,并且妖精 j 在区间 内。正邪会试图让妖精 击败妖精 。为了防止实力悬殊,它们还满足:



正邪希望你找到 的最大值。特别地,如果不存在合法数对,你只要输出 就行了。

输入描述

第一行两个整数,。含义如题面所示。

第二行 个整数 ,表示序列

接下来 行,每行四个整数,l_1,r_1,l_2,r_2 ,表示一组询问。

输出描述

 行,每行输出一个整数,表示最大的  ,或者不存在任何合法数对时输出的 

示例1

输入:

6 3
8 6 2 3 5 6
2 5 1 3
1 1 3 6
3 5 1 2

输出:

7
14
0

说明:

对于询问 \mathrm 1 ,有两对妖精  \mathrm (3,4) 和\mathrm (3,5) 满足下克上的条件。但因为 \mathrm{2+5>2+3},因此精彩度最大为 \mathrm 7  。
对于询问 \mathrm 2 ,有两对妖精 \mathrm (1,5)\mathrm (1,6) 满足下克上的条件。但因为 \mathrm 8+6>8+5 ,因此精彩度最大为 \mathrm 14
对于询问 \mathrm 3 ,不存在任何符合条件的妖精对。因此直接输出 \mathrm 0

示例2

输入:

10 10
106 42 110 126 7 52 68 70 73 118 
10 10 5 5
9 10 4 4
1 5 4 6
4 9 9 9
4 5 1 3
1 6 1 8
3 5 5 9
4 4 1 3
5 5 4 8
2 4 6 7

输出:

0
0
0
199
236
236
199
236
0
194

说明:

这里本应该有个绝妙的说明,但是这里空白太小了写不下。

原站题解

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

C++(clang++ 11.0.1) 解法, 执行用时: 2193ms, 内存消耗: 76040K, 提交时间: 2023-04-26 20:31:40

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N=2e7+10,V=1e9,mod=998244353;
void add(int &a,ll b);
int lc[N],rc[N],cnt[N],root[N],idx=0;
int l1,l2,r2,r1,x,y,ans;
void modify(int &a,int b,int l,int r,int x)
{
	a=++idx;
	lc[a]=lc[b];rc[a]=rc[b];cnt[a]=cnt[b]+1;
	if(l==r)return ;
	int mid=l+r>>1;
	if(mid>=x)modify(lc[a],lc[b],l,mid,x);
	else modify(rc[a],rc[b],mid+1,r,x);
}
int quary(int x,int y,int l,int r,int t)
{
	if(l>t||cnt[x]-cnt[y]==0)return -1;
	if(l==r)return l;
	int mid=l+r>>1,res=-1;
	if(t>mid) res=quary(rc[x],rc[y],mid+1,r,t);
	if(!~res)return quary(lc[x],lc[y],l,mid,t);
	return res;
}
void quary(int f,int t){if(f)x=quary(root[r1],root[l1-1],1,V,t);else y=quary(root[r2],root[l2-1],1,V,t);}
int main()
{
  	int n,m;
  	scanf("%d%d",&n,&m);
  	for(int i=1;i<=n;i++)
  	{
  		int num;
  		scanf("%d",&num);
  		modify(root[i],root[i-1],1,V,num);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
		quary(1,V);
		quary(0,V);
		while(1)
		{
			if(x==-1||y==-1||(y>=x/2&&y<x))break;
			if(y<x/2)quary(1,2*y+1);
			else quary(0,x-1);
		}				
		if(x==-1||y==-1)ans=0;
		else ans=x+y;
		printf("%d\n",ans);

	}
}

void add(int &a,ll b){a=((a+b)%mod+mod)%mod;return;}

上一题