POJ 2796 Feel Good(単調スタック+線分樹)
7928 ワード
Feel Good(単調なスタック+線分樹)
Time Limit:3000 MS
メモリLimit:65536 K
Total Submissions:17746
Acceepted:4900
Case Time Limit:1000 MS
Special Jundge
Description
Bill isdeveloloping a new mathematititititititttttmatititittheory for hu man emiotions.Hs recentininvevevevestininininininininindededicated to stuudididididididididididiinininininininininininininininininininininininininininininininininininininggggggggshshshshshshshshshshshshshshshshaaaaaaattttttttttttttttttttgogogogogogogogogodddddddddadadadadadae of the day.The greater the emotional value is,the better the days.Bill suggaests that the value of some period of huoman life is propotionl to the sum of the emotion values of the days in the given period,multilied by the smalest emational value of the day in it.This schema reflectthat good on average period can be greatly spoled by one very bad day.Now Bill is planing to investigate to to to investinit the fithis of.
Input
The first line of the input contains n-the number of days of Bill's life he is planing to investigate(1==n==100,000)The ret of the file contains n integer numbers a 1,a 2,…randing from 0-theembles
Output
Print the greatest value of some period of Bill’s life in the first line.And on the second line print two numbers l and such the period from l-th to r-th day of Bill's life(inclive)has the grease the the Prease the part vars part bles.
Sample Input
は長さnのシーケンスを与え、区間がこの区間の数と*この区間の最小値を求める値を探し出し、この値と区間の左右境界を出力します.
問題を解く構想
この問題はHDU 1506と少し似ています.その核心思想は各最適区間に対して、境界近傍の要素が区間の最小値より大きいと仮定して、隣接元素は合併されなければなりません.しかし、この最適区間は変更されました.これは仮定と違って、境界の臨界条件は最初の区間の最小値より小さい数が現れます.各要素については、左から(右から)一番目の小さい数を見つけて、最後に最大値を出せばいいです.区間の需要と私が使う線分樹に関連しています.注意データ範囲は、爆発します.
Time Limit:3000 MS
メモリLimit:65536 K
Total Submissions:17746
Acceepted:4900
Case Time Limit:1000 MS
Special Jundge
Description
Bill isdeveloloping a new mathematititititititttttmatititittheory for hu man emiotions.Hs recentininvevevevestininininininininindededicated to stuudididididididididididiinininininininininininininininininininininininininininininininininininininggggggggshshshshshshshshshshshshshshshshaaaaaaattttttttttttttttttttgogogogogogogogogodddddddddadadadadadae of the day.The greater the emotional value is,the better the days.Bill suggaests that the value of some period of huoman life is propotionl to the sum of the emotion values of the days in the given period,multilied by the smalest emational value of the day in it.This schema reflectthat good on average period can be greatly spoled by one very bad day.Now Bill is planing to investigate to to to investinit the fithis of.
Input
The first line of the input contains n-the number of days of Bill's life he is planing to investigate(1==n==100,000)The ret of the file contains n integer numbers a 1,a 2,…randing from 0-theembles
Output
Print the greatest value of some period of Bill’s life in the first line.And on the second line print two numbers l and such the period from l-th to r-th day of Bill's life(inclive)has the grease the the Prease the part vars part bles.
Sample Input
6
3 1 6 4 5 2
Sample Output60
3 5
題意は長さnのシーケンスを与え、区間がこの区間の数と*この区間の最小値を求める値を探し出し、この値と区間の左右境界を出力します.
問題を解く構想
この問題はHDU 1506と少し似ています.その核心思想は各最適区間に対して、境界近傍の要素が区間の最小値より大きいと仮定して、隣接元素は合併されなければなりません.しかし、この最適区間は変更されました.これは仮定と違って、境界の臨界条件は最初の区間の最小値より小さい数が現れます.各要素については、左から(右から)一番目の小さい数を見つけて、最後に最大値を出せばいいです.区間の需要と私が使う線分樹に関連しています.注意データ範囲は、爆発します.
/*
_ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\__/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
BUG
*/
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5+50;
long long tree[maxn<<2],arr[maxn];
int l[maxn],r[maxn];
stack<int> s;
void pushup(int rt)
{
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
void build(int l,int r,int rt)
{
if(l==r)
{
tree[rt]=arr[l];
return;
}
int m=l+r>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
pushup(rt);
}
long long query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return tree[rt];
int m=l+r>>1;
long long ans=0;
if(L<=m) ans+=query(L,R,l,m,rt<<1);
if(R> m) ans+=query(L,R,m+1,r,rt<<1|1);
return ans;
}
int main()
{
#ifdef DEBUG
freopen("in.txt","r",stdin);
#endif // DEBUG
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",&arr[i]);
build(1,n,1);
while(s.size()) s.pop();
for(int i=1; i<=n; i++)
{
while(s.size()&&arr[s.top()]>=arr[i]) s.pop();
if(s.empty()) l[i]=1;
else l[i]=s.top()+1;
s.push(i);
}
while(s.size()) s.pop();
for(int i=n; i>=1; i--)
{
while(s.size()&&arr[s.top()]>=arr[i]) s.pop();
if(s.empty()) r[i]=n;
else r[i]=s.top()-1;
s.push(i);
}
long long ans=-0x3f3f3f3f;
int pos=0;
for(int i=1; i<=n; i++)
{
long long t=query(l[i],r[i],1,n,1)*arr[i];
if(ansprintf("%lld
%d %d
",ans,l[pos],r[pos]);
return 0;
}