这题可用贪心+二分来实现,注意一个区间的舒适度是由区间最小值和区间和两个要素决定的,我们要控制变量,从1-n进行遍历,将a[i]作为这个区间的最小值,那么我们希望这个区间和尽可能地大才能让舒适度达到最大,同时我们要保证这个区间的最小值是a[i]。我们从i向两边延伸,找到小于a[i]的值就是这个区间的边界。我们可以用单调队列和ST表+二分实现。
#include
#define ll long long
using namespace std;
ll n,sum[100005],st[100005][30],ans=0;
ll ask(int l,int r){
int x=log2(r-l+1);
return min(st[l][x],st[r-(1<>n;
for(int i=1;i<=n;i++){
cin>>st[i][0];
sum[i]=sum[i-1]+st[i][0];
}
for(int j=1;(1<
动态规划+单调队列优化。
很明显,到达一个点的冰冻值是由[i-r,i-l]区间的冰冻值转移过来的,我们要的是区间的最大值,就用单调队列维护。注意DP数组要初始化为负无穷,因为有些点是不可能到达的。
#include
#define ll long long
using namespace std;
int n,l,r,dp[400005],a[400005],ans=-2147483648;
dequeq;
void put(int x){
while(!q.empty()&&dp[q.front()]>n>>l>>r;
for(int i=0;i<=n;i++){
cin>>a[i];
}
memset(dp,-0x3f,sizeof(dp));
dp[0]=0;
for(int i=l;i<=n+r;i++){
if(i-l>=0) put(i-l);
if(i-r-1>=0) out(i-r-1);
if(!q.empty()) dp[i]=dp[q.front()]+a[i];
if(i>n) ans=max(ans,dp[i]);
}
cout<
二维队列,依照题意模拟就行。
#include
#define ll long long
using namespace std;
queueteam[305];
queueq;
int n,m,a[100005],t,x;
string s;
int main() {
cin>>n>>m;
for(int i=0;i>a[i];
}
cin>>t;
while(t--){
cin>>s;
if(s=="push"){
cin>>x;
if(team[a[x]].empty()){
q.push(a[x]);
}
team[a[x]].push(x);
}
else{
cout<
#include
#define ll long long
using namespace std;
int n,a[1000005],ans[1000005];
stackq;
int main() {
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=n;i>=1;i--){
while(!q.empty()&&a[q.top()]<=a[i]){
q.pop();
}
if(!q.empty()) ans[i]=q.top();
q.push(i);
}
for(int i=1;i<=n;i++){
cout<
单调栈是单调队列阉割版
#include
#define ll long long
using namespace std;
ll n,a[3000005],ans[3000005];
stackq;
int main() {
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=n;i>=1;i--){
while(!q.empty()&&a[q.top()]<=a[i]){
q.pop();
}
if(!q.empty()) ans[i]=q.top();
q.push(i);
}
for(int i=1;i<=n;i++){
cout<
依旧单调栈
#include
#define ll long long
using namespace std;
char ch;
stackq;
ll temp;
int main() {
while(cin>>ch){
if(ch=='@') break;
else if(ch=='.') q.push(temp),temp=0;
else if(ch>='0'&&ch<='9') temp=temp*10+ch-'0';
else{
int x=q.top();
q.pop();
int y=q.top();
q.pop();
if(ch=='+') q.push(x+y);
if(ch=='-') q.push(y-x);
if(ch=='*') q.push(y*x);
if(ch=='/') q.push(y/x);
//cout<
依旧模拟
#include
#define ll long long
using namespace std;
int a[300],sum=0;
int main() {
string s;
cin>>s;
for(int i=0;i
依旧单调栈或模拟
#include
#define ll long long
using namespace std;
ll a,sum=0,temp;
char ch;
vectorarr;
int main() {
cin>>temp;
while(cin>>ch>>a){
//if(ch=='@') break;
if(ch=='+') arr.push_back(temp%10000),temp=a%10000;
else temp=((temp%10000)*(a%10000))%10000;
}
arr.push_back(temp);
for(auto it:arr){
sum=(sum+it)%10000;
}
cout<
依旧ST表
#include
#define ll long long
using namespace std;
int n,q,stmin[50005][30],stmax[50005][30];
int main() {
cin>>n>>q;
for (int i = 1; i <= n; i++) cin >> stmax[i][0],stmin[i][0]=stmax[i][0];//建表
for (int j = 1; (1 << j) <= n; j++)//总包含数字不超过n
{
for (int i = 1; i + (1 << j) - 1 <= n; i++)//确保是子区间,不越界
{
stmin[i][j] = min(stmin[i][j - 1], stmin[i + (1 << j - 1)][j - 1]);
stmax[i][j] = max(stmax[i][j - 1], stmax[i + (1 << j - 1)][j - 1]);
}
}
int l, r;//查询
while(q--){
cin >> l >> r;
int x = log2(r - l + 1);
cout << max(stmax[l][x], stmax[r - (1 << x) + 1][x] )-min(stmin[l][x], stmin[r - (1 << x) + 1][x] )<< endl;
}
return 0;
}