http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1205
破oj,%lld过不了,改成cout或者%I64D就过了,害的老子调试了这么长时间,而且这题的数据也比较水,大数据根本就没有几组,我都开始怀疑人生了!!!!
值得注意的几点,第一,一定要手推一遍样例,第二元素重复的时候一定需要想清楚,因为一个区间只能用来算一次,所以要在往左的时候应该是到等于,往右的时候不能到等于!而且最好是降低常数复杂度,一种顺序更新的时候最好就把大于和小于的同时都记录下来,可以开两个栈嘛!
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
struct node{
ll v,p;
}a[maxn];
ll l[maxn],r[maxn];
ll t,n;
int main(){
cin>>t;int count=1;
while(t--){
stack<node>q;memset(a,0,sizeof(a));
scanf("%lld",&n);
for(int i=1;i<=n;i++) {
scanf("%lld",&a[i].v);a[i].p=i;
}
while(q.size()!=0) q.pop();
q.push(a[1]);l[1]=0;
for(int i=2;i<=n;i++){
while(q.size()!=0&&q.top().v>=a[i].v){
q.pop();
}
if(q.size()!=0)l[i]=q.top().p;
else l[i]=0;
q.push(a[i]);
}
while(q.size()!=0) q.pop();
q.push(a[n]);r[n]=n+1;
for(int i=n-1;i>=1;i--){
while(q.size()!=0&&q.top().v>a[i].v){
q.pop();
}
if(q.size()!=0)r[i]=q.top().p;
else r[i]=n+1;
q.push(a[i]);
}
/*for(int i=1;i<=n;i++){
cout<<"== "<<l[i]<<" "<<r[i]<<" "<<(r[i]-i)*(i-l[i])<<endl;
}*/
ll ans=0;
for(ll i=1;i<=n;i++){
ans-=a[i].v*(r[i]-i)*(i-l[i]);
}
while(q.size()!=0) q.pop();
q.push(a[1]);l[1]=0;
for(int i=2;i<=n;i++){
while(q.size()!=0&&q.top().v<=a[i].v){
q.pop();
}
if(q.size()!=0)l[i]=q.top().p;
else l[i]=0;
q.push(a[i]);
}
while(q.size()!=0) q.pop();
q.push(a[n]);r[n]=n+1;
for(int i=n-1;i>=1;i--){
while(q.size()!=0&&q.top().v<a[i].v){
q.pop();
}
if(q.size()!=0)r[i]=q.top().p;
else r[i]=n+1;
q.push(a[i]);
}
/* for(int i=1;i<=n;i++){
cout<<"== "<<l[i]<<" "<<r[i]<<" "<<(r[i]-i)*(i-l[i])<<endl;
}*/
for(ll i=1;i<=n;i++){
ans+=a[i].v*(r[i]-i)*(i-l[i]);
}
ans+=(ll)(1+n)*n/2;
printf("Case %d: ",count++);printf("%I64d\n",ans);
}
}