题目大意:
求前i天连续一段时间的最大利润方法数
解题思路:
既然是要求最大利润的方法数量,首先要确定最大利润是多少,用一个变量保存并实时更新,因为利润范围较大,用map保持当前最大利润的方法数,用一个数组保存当前天数的答案,特别注意如果连续出现两个大小相等的相反数并且先出现负数或者当前利润为0时,方案数要加一(出现两数之前最大值max,出现负数时max + 负数 < max,再出现正数与负数抵消,两天都选时是一个全新的方案)
#include<bits/stdc++.h>
using namespace std;
#pragma GCC optimize(3)
#define sub substr
#define ll long long
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl '\n'
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define upfor(i, st, ed) for(int i = st; i <= ed; ++i)
#define dnfor(i, st, ed) for(int i = st; i >= ed; --i)
#define upfor_(i, st, ed) for(int i = st; i < ed; ++i)
#define dnfor_(i, st, ed) for(int i = st; i < ed; --i)
#define map unordered_map
#define pqu priority_queue /*优先队列 */
#define pb push_back
#define pf push_front
#define eb emplace_back
#define ppb pop_back
#define fbo friend bool operator <
using vi = vector<int>;
using vll = vector<ll>;
using vd = vector<double>;
using vc = vector<char>;
using vstr = vector<string>;
//
//
map<ll , ll> mp;//存当前利润的方法数
ll n , m , t;
ll net[1000005] = {0} , ans[1000005] = {0};//net存数据,ans存答案
signed main(){
ios;
cin >> n >> m;
upfor(i , 1 , n)cin >> net[i];
// mmax存最大利润,cur存当前利润 ,sum存连续区域方法数
ll mmax = net[1] , cur = 0 , sum = 0;
upfor(i , 1 , n){
// 如果当前区间利润小于0 ,重新分配数据
// 与前面的数据断开联系 ,不影响结果,因为前面的数据已经再mp中保存
// 而后面的数据加上这一个负数必定比最大利润小
if(cur < 0){
sum = 1;
cur = 0;
// 如果当前区间利润等于0,就是思路里的特殊情况
}else if(cur == 0) sum++;
cur += net[i];
if(cur >= mmax){
mmax = cur;
mp[mmax] += sum;
}
ans[i] = mp[mmax];
}
upfor(i , 1 , m){
cin >> t;
cout << ans[t] << endl;
}
return 0;
}
/*
1.数组大小
2.输出格式
3.看明白题意再解题
4.选择语言
*/
反正没人看懒得说了嘿嘿