思路大体就是代码开头几句,应该是对的,但不知道哪里炸了,只有Sub2的过了,希望有大佬能帮帮蒟蒻。 万分感谢。
/*
对于a[l]!=a[l - 1]的,按Sub2计算
对于a[l]==a[l - 1]的,f[l]会有区间左边的贡献,需要减去
记录每个数的起止位置就可以计算
只需要二分查找
a <= 1e9 离散化。
好像可以不用离散化,对于每个a[i],记录它的起始位置,而对于起始位置,记录它的结束位置即可
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll N = 2e5 + 86, mod = 1e9 + 7;
ll n, q, len = 0;
ll a[N], f[N], st[N], ed[N];
int main() {
scanf("%lld",&n);
for(ll i = 1;i <= n;i++) scanf("%lld",&a[i]);
for(ll i = 1;i <= n;i++) {
len++;
f[i] = (f[i - len] + (len * (len + 1) / 2 )% mod) % mod;
st[i] = i - len + 1;//记录起点
ed[st[i]] = i;//记录终点
if(a[i] != a[i + 1] && i!= n) len = 0;
}
scanf("%lld",&q);
while(q--) {
ll op,l,r;
scanf("%lld",&op);
if(op == 1) {
scanf("%lld",&a[++n]);
if(a[n] != a[n - 1]) len = 0;
len++;
f[n] = (f[n - len] + ( len * (len + 1) / 2 ) % mod) % mod;
st[n] = n - len + 1;
ed[st[n]] = n;
}
else {
scanf("%lld%lld",&l,&r);
if(a[l] != a[l - 1]) {
printf("%lld\n",((f[r] - f[l - 1]) % mod + mod) % mod);
}
else {
// puts("Hello!");
ll ST = st[l];
ll ED = ed[ST];
long long ans = (f[r] - f[ED] + mod) % mod;
ans += (ED - l + 1) * (ED - l + 2) / 2 % mod;
ans %= mod;
printf("%lld\n",ans);
}
}
}
return 0;
}