POJ 2796 Feel Good 并查集
答案为0时要输出一个合理的区间...这是个坑.
-----------------------
const int maxn=110000; const int maxm=10000; int n; int a[maxn]; struct Dat{ int v; int idx; }; bool cmp(const Dat& a,const Dat& b){ return a.v>b.v; } Dat b[maxn]; int L[maxn],R[maxn],Mis[maxn]; int pa[maxn]; void makeset(int n){ for (int i=0;i<=n;i++) pa[i]=i; } int findset(int x){ if (x!=pa[x]) pa[x]=findset(pa[x]); return pa[x]; } void unionset(int x,int y){ x=findset(x); y=findset(y); if (x!=y){ //cerr<<"union "<<x<<" "<<y<<endl; pa[x]=y; L[y]=min(L[x],L[y]); R[y]=max(R[x],R[y]); Mis[y]=min(Mis[x],Mis[y]); //cerr<<"now "<<L[y]<<" "<<R[y]<<" "<<Mis[y]<<endl<<endl; } } LL sum[maxn]; int main(){ while (~scanf("%d",&n)){ makeset(n); sum[0]=0; for (int i=1;i<=n;i++){ scanf("%d",&a[i]); b[i].v=a[i]; b[i].idx=i; L[i]=R[i]=i; Mis[i]=a[i]; sum[i]=sum[i-1]+a[i]; } sort(b+1,b+1+n,cmp); LL ans=0; int ansL=1,ansR=1; for (int i=1;i<=n;i++){ //cerr<<b[i].v<<" "<<b[i].idx<<endl; if (b[i].idx>1&&b[i].v<=Mis[findset(b[i].idx-1)]){ unionset(b[i].idx,b[i].idx-1); } if (b[i].idx<n&&b[i].v<=Mis[findset(b[i].idx+1)]){ unionset(b[i].idx,b[i].idx+1); } int id=findset(b[i].idx); LL tmp=(LL)Mis[id]*(sum[R[id]]-sum[L[id]-1]); if (ans<tmp){ ans=tmp; //cerr<<ans<<" "<<id<<" "<<Mis[id]<<" "<<R[id]<<" "<<L[id]<<endl; ansL=L[id]; ansR=R[id]; } } printf("%I64d\n",ans); printf("%d %d\n",ansL,ansR); } return 0; }
-----------------------