藍橋杯_數組操作
問題描述
給出一個長度為 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;
}