牛可乐发红包脱单ACM赛$
B 小a的旅行计划
oeis
http://oeis.org/search?q=0%2C3%2C30+&language=english&go=Search
int main(void)
{
LL n;
cin>>n;
n++;
LL ans = (qpow(4,n)-4*qpow(3,n)+6*qpow(2,n)-4)*qpow(8,mod-2);
ans = (ans%mod+mod)%mod;
cout<<ans<<endl;
return 0;
}
C 区区区间间间
vl,r=max(ai−aj)(l<=i,j<=r)
i∑nj+1∑nvi,j
对于每一个a[i] 左边有 连续的x个比它小,右边有连续的y个比它大
那么a[i] 作为这个区间的最大值,被统计的次数就是(x+1)(y+1)-1
通过单调队列可以求出x和y
#include <bits/stdc++.h>
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define Pb push_back
#define FI first
#define SE second
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define IOS ios::sync_with_stdio(false)
#define DEBUG cout<<endl<<"DEBUG"<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int prime = 999983;
const int INF = 0x7FFFFFFF;
const LL INFF =0x7FFFFFFFFFFFFFFF;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-6;
const LL mod = 1e9 + 7;
LL qpow(LL a,LL b){LL s=1;while(b>0){if(b&1)s=s*a%mod;a=a*a%mod;b>>=1;}return s;}
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
int dr[2][4] = {1,-1,0,0,0,0,-1,1};
typedef pair<int,int> P;
const int maxn = 1e5+100;
int a[maxn];
int s[maxn];// 单调栈
// 第一遍求在这个区间里面最大
int pre[maxn];
int nxt[maxn];
int main(void)
{
int T,n;
cin>>T;
while(T--){
scanf("%d",&n);
for(int i = 1;i <= n; ++i){
scanf("%d",&a[i]);
}
int t = 0;
for(int i = 1;i <= n; ++i){
pre[i] = nxt[i] = 0;
while(t > 0&&a[i] > a[s[t]]) nxt[s[t]] = i,t--;
pre[i] = s[t];
s[++t] = i;
// cout<<pre[i]<<" ";
}
while(t > 0)
nxt[s[t]] = n+1,t--;
LL ans = 0;
for(int i = 1;i <= n; ++i){
ans += 1ll*a[i]*(nxt[i]-i)*(i-pre[i]);
}
t = 0;
for(int i = 1;i <= n; ++i){
pre[i] = nxt[i] = 0;
while(t > 0&&a[i] < a[s[t]]) nxt[s[t]] = i,t--;
pre[i] = s[t];
s[++t] = i;
}
while(t > 0)
nxt[s[t]] = n+1,t--;
for(int i = 1;i <= n; ++i){
ans -= 1ll*a[i]*(nxt[i]-i)*(i-pre[i]);
}
printf("%lld\n",ans);
}
return 0;
}