蓝桥杯_数组操作

蓝桥杯_数组操作

问题描述

  给出一个长度为 n 的数组 {A_i},由 1 到 n 标号 , 你需要维护 m 个操作。
  操作分为三种,输入格式为:

  1 l r d,将数组中下标 l 到 r 的位置都加上 d,即对于 l<=i<=r,执行A_i=A_i+d。

  2 l_1 r_1 l_2 r_2,将数组中下标为 l_1 到 r_1 的位置,赋值成 l_2 到 r_2 的值,保证 r_1-l_1=r_2-l_2。
  换句话说先对 0<=i<=r_2-l_2 执行 B_i=A_(l_2+i),再对 0<=i<=r_1-l_1 执行 A_(l_1+i)=B_i,其中 {B_i} 为一个临时数组。

  3 l r,求数组中下标 l 到 r 的位置的和,即求出 ∑_(i=l到r) A_i 。

输入格式

  从标准输入读入数据。
  第一行一个整数 Case,表示测试点编号,其中 Case=0 表示该点为样例。
  第二行包含两个整数 n,m。保证 1<=n,m<=10^5。
  第三行包含 n 个整数 A_i,表示这个数组的初值。保证 0<=A_i<=10^5。
  接下来 m 每行描述一个操作,格式如问题描述所示。
  对于操作中提到每个数,满足 0<=d<=10^5,1<=l<=r<=n,1<=l_1<=r_1<=n,1<=l_2<=r_2<=n,r_1-l_1=r_2-l_2。

输出格式

  输出到标准输出。
  对于每次 3 操作输出一行一个数,表示求和的结果。

样例输入

0
5 6
1 2 3 4 5
2 1 3 3 5
3 3 5
1 2 4 2
3 3 5
2 1 3 3 5
3 1 5

样例输出

14
18
29

数据规模和约定

测试点 n,m 其他约束
1,2 <=10^3
3,4 <=10^5 没有2操作
5,6,7 <=10^5 n 为偶数,且所有2操作满l_1=1,r_1=n/2 ,l_2=n/2+1,r_2=n
8,9,10 <=10^5

思路

经常听说蓝桥杯的题目很简单,emm,差点被人骗了;

好吧其实这道题的难点主要在理解题意和数据处理;

大量的数据导致程序会超时,所以我先写了模板,获得二十分。以后再尝试优化:

代码

#include <bits/stdc++.h>

using namespace std;
typedef unsigned long long ull;

class Solution{
public:
	vector<int> nums;
	vector<ull> ans;
	int N, M;
	void func1(int, int, int);
	void func2(int, int, int, int);
	void func3(int, int);
	void show();
	void solve();
};

void Solution::show() {
	for (int i=0; i<N; i++) {
		cout<<nums[i]<<" ";
	}
	cout<<endl;
}
// 对应数组操作一
void Solution::func1(int begin, int end, int num) {
	for (int i=begin; i<end; i++) {
		nums[i] += num;
	}
}
// 对应数组操作二
void Solution::func2(int num1, int num2, int begin, int end) {
	vector<int> tmp;
	for (int i=begin; i<end; i++) {
		tmp.push_back(nums[i]);
	}
	for (int i=num1; i<num2; i++) {
		nums[i] = tmp[i-num1];
	}
	tmp.clear();
}
// 对应数组操作三
void Solution::func3(int begin, int end) {
	ull sum = 0;
	for (int i=begin; i<end; i++) {
		sum += nums[i];
	}
	cout<<sum<<endl;
	//ans.push_back(sum);
}
// 解决函数
void Solution::solve() {
	int flag = 0;
	int num1, num2;
	int begin, end, num;
	
	cin>>flag;
	cin>>N>>M;
	nums.resize(N);
	
	for (int i=0; i<N; i++) {
		cin>>nums[i];
	}

	for (int i=0; i<M; i++) {
		cin>>flag;
		switch (flag) {
			case 0:break;
			case 1:
				cin>>begin>>end>>num;
				func1(begin-1, end, num);
				//show();
				break;
			case 2:
				cin>>num1>>num2>>begin>>end;
				func2(num1-1, num2, begin-1, end);
				//show();
				break;
			case 3:
				cin>>begin>>end;
				func3(begin-1, end);
				//show();
				break;
		}
	}
}

int main(void) {
	Solution su;
	su.solve();
	return 0;
} 
posted @ 2020-06-30 15:04  樱花小猪  阅读(777)  评论(0编辑  收藏  举报