题目链接:
https://codeforces.com/contest/1151/problem
题目大意:
a
[
i
]
a_[i]
a[i]表示
i
i
i号节点的权值,
i
i
i号节点和
i
−
1
i-1
i−1号,
i
+
1
i+1
i+1号节点相邻
f
(
l
,
r
)
f(l,r)
f(l,r)表示只留下权值在
[
l
,
r
]
[l,r]
[l,r]范围内的节点后,连通块的个数
求
∑
l
=
1
n
∑
r
=
i
n
f
(
l
,
r
)
\sum_{l=1}^{n}\sum_{r=i}^{n}f(l,r)
∑l=1n∑r=inf(l,r)
题解思路
对于这种类型的计数题目,关键点在于求得每个点的独立贡献。 \textbf{对于这种类型的计数题目,关键点在于求得每个点的独立贡献。} 对于这种类型的计数题目,关键点在于求得每个点的独立贡献。
考虑一种dp思想,对于
i
i
i号节
(
i
≥
1
)
(i\geq1)
(i≥1)点,我们只考虑和
i
−
1
i-1
i−1号节点的关系:
1.
1.
1.
a
i
>
a
i
−
1
a_{i}>a_{i-1}
ai>ai−1 那么左端点取值在
(
a
i
−
1
,
a
i
]
(a_{i-1},a_{i}]
(ai−1,ai]时,
a
i
a_i
ai会独立产生贡献
右端点取值可以取
[
a
i
,
n
]
[a_{i},n]
[ai,n]
2.
2.
2.
a
i
<
a
i
−
1
a_{i}<a_{i-1}
ai<ai−1 那么右端点取值在
[
a
i
,
a
i
−
1
)
[a_{i},a_{i-1})
[ai,ai−1)时,
a
i
a_i
ai会独立产生贡献
左端点取值可以取
[
1
,
a
i
]
[1,a_{i}]
[1,ai]
3.
3.
3.
a
i
=
a
i
−
1
a_{i}=a_{i-1}
ai=ai−1
a
i
a_{i}
ai不会产生独立贡献
这样扫一遍之后就可求得每个节点的独立贡献了
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define int ll
#define debug cout<<"fuck"<<endl;
#define pb push_back
#define endl '\n'
bool cmp(int a,int b)
{
return a>b;
}
ll quick_pow_mod(ll a,ll b,ll c) { ll res=1;while(b) { if(b & 1) { res=(res*a)%c; }a=(a*a)%c;b=b>>1; }return res; }
const int maxn=(int)1e5+5;
const int mod=(int)1e9+7;
int n,m;
int a[maxn];
signed main()
{
IOS
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int res=a[1]*(n-a[1]+1);
for(int i=2;i<=n;i++)
{
if(a[i]>a[i-1])
{
res+=(a[i]-a[i-1])*(n-a[i]+1);
}
if(a[i]<a[i-1])
{
res+=a[i]*(a[i-1]-a[i]);
}
}
cout<<res<<endl;
return 0;
}