列表

详情


NC25674. 慢慢变小的序列

描述

给一个长度为 n 的序列,你需要支持以下两种操作: 
操作 1:L R X Y,对所有赋值 ,其中 L, R, X, Y 均为整数,且有
操作 2:x,询问A_x的值,这里 x 是整数,且有。 

输入描述

第一行包含两个整数,分别表示序列长度为以及操作次数,

第二行是 n 个整数 

接下来 q 行,每行第一个数字表示操作类型,接下来输入对应题面描述。

输出描述

对于每个操作 2,输出对应查询的结果。

示例1

输入:

5 5
0 0 0 0 0
2 1
1 1 5 2 -1
2 5
1 1 2 -1 2
2 1

输出:

0
-2
-1

原站题解

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

C++14(g++5.4) 解法, 执行用时: 329ms, 内存消耗: 38104K, 提交时间: 2019-05-24 11:44:46

#include<bits/stdc++.h>
using namespace std;
#define N 1000000+100
//typedef long long ll;

#define int long long
int tree[12][N*4],a[N];

const int INF=1e9;
void add(int i,int l,int r,int x,int y,int k,int Tree[])
{
    if(l>=x&&r<=y){
        Tree[i]=min(k,Tree[i]);
        return ;
    }
    int mid=(l+r)/2;
    if(mid>=x)add(i*2,l,mid,x,y,k,Tree);
    if(mid+1<=y)add(i*2+1,mid+1,r,x,y,k,Tree);
}
int query(int i,int x,int l,int r,int Tree[])
{
    if(l==r)
    return Tree[i];
    int mid=(l+r)/2;
    if(x>=mid+1)return  min(query(i*2+1,x,mid+1,r,Tree),Tree[i]);
    else return min(query(i*2,x,l,mid,Tree),Tree[i]);
}
signed  main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,q;
    cin>>n>>q;
    for(int i=0;i<=10;i++)
    for(int j=0;j<=n*4;j++)
    tree[i][j]=INF;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    int flag;
    while(q--)
    {
        cin>>flag;
        if(flag==1){
            int l,r,x,y;
            cin>>l>>r>>x>>y;
            add(1,1,n,l,r,x-y*l,tree[y+5]);
        }
        else{
            int x;
            cin>>x;
            int ans=a[x];
            for(int i=0;i<=10;i++)
            {
                ans=min(ans,(i-5)*x+query(1,x,1,n,tree[i]));
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 108ms, 内存消耗: 19876K, 提交时间: 2023-03-23 18:11:01

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e5+10;
const int INF = 1e9+10;
int tree[12][maxn<<2],a[maxn],n,q;
int MIN(int x,int y){
	return x<y?x:y;
}
void Init(){
	for(int i=0;i<12;i++)
		for(int j=0;j<(maxn<<2);j++) tree[i][j] = INF;
}
void Update(int L,int R,int C,int ta[],int rt,int l,int r){
	if(L<=l&&r<=R){
		ta[rt] = MIN(ta[rt],C);
		return ;
	}
	int mid = (l+r)>>1;
	if(L<=mid) Update(L,R,C,ta,rt<<1,l,mid);
	if(R>mid) Update(L,R,C,ta,rt<<1|1,mid+1,r);
}
int Query(int pos,int ta[],int rt,int l,int r){
	if(l==r) return ta[rt];
	int mid = (l+r)>>1;
	if(pos<=mid) return MIN(ta[rt],Query(pos,ta,rt<<1,l,mid));
	else return MIN(ta[rt],Query(pos,ta,rt<<1|1,mid+1,r));
}
int main(void){
	Init();
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=q;i++){
		int op;scanf("%d",&op);
		if(op==1){
			int l,r,x,y;scanf("%d%d%d%d",&l,&r,&x,&y);
			Update(l,r,x-l*y,tree[y+5],1,1,n);
		}else{
			int x;scanf("%d",&x);
			for(int i=0;i<=10;i++) a[x] = MIN(a[x],(i-5)*x+Query(x,tree[i],1,1,n));
			printf("%d\n",a[x]);
		}
	}
	
	return 0;
}

上一题