列表

详情


NC231646. 一道简单题

描述

给定一个长度为 n 的数组 a ,进行 q 次询问
对于每个询问,你将得到三个整数 l,r,x ,请你计算 T(l,r,x) 的值.
.

输入描述

第一行包含一个整数 n ()  --- 数组 a 的大小。
第二行包含 n 个整数 .
第三行包含 1 个整数 q () --- 问题的数量.
接下来 q 行每行包含 3 个整数 l_i,r_i,x_i () --- 表示第 i 个问题

输出描述

输出一行,包含 q 个整数  --- 表示问题的答案

示例1

输入:

3
3 2 3
1
1 3 3

输出:

9

示例2

输入:

5
2 1 3 3 4
3
1 3 3
1 4 5
1 2 5

输出:

9 16 8

原站题解

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

C++(clang++ 11.0.1) 解法, 执行用时: 161ms, 内存消耗: 8936K, 提交时间: 2023-05-18 23:30:45

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+5;
int n,m,totq;
ll a[N],ans[N];
struct Line{
	int id,l,r,x;
	friend bool operator<(Line a,Line b){
		return a.x<b.x;
	}
}ask[N];
struct Q{
	int id;
	ll val,sum;
}q[N];


ll get(int x){
	
	int l=1,r=totq;
	while(l<=r){
		int m=(l+r)>>1;
		if(q[m].id<x) l=m+1;
		else r=m-1;
	}
	
	return q[l].sum+q[l].val*(x-q[l-1].id);
} 

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
	scanf("%d",&m);
	for(int i=1;i<=m;++i){
		ask[i].id=i;
		scanf("%d %d %d",&ask[i].l,&ask[i].r,&ask[i].x);
	}
	sort(ask+1,ask+m+1);
	
	int pos=0;
	
	for(int i=1;i<=m;++i){
		while(pos<=ask[i].x){
			while(a[pos]<=a[pos+1]&&pos+1<=ask[i].x) pos++;
			while(totq&&q[totq].val<=a[pos]) totq--;
			
			++totq;
			if(totq==1) q[totq]=(Q){pos,a[pos],0};
			else q[totq]=(Q){pos,a[pos],q[totq-1].sum+q[totq-1].val*(q[totq-1].id-q[totq-2].id)}; 
		
			pos++;
		}

		ans[ask[i].id]=get(ask[i].r)-get(ask[i].l-1);
	}

	for(int i=1;i<=m;++i) printf("%lld ",ans[i]);
} 

上一题