蓝桥杯_数组操作
问题描述
给出一个长度为 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;
}