题解:P3246 [HNOI2016] 序列
这是一篇五分钟可以写完的乱搞做法
solution
看到这个询问第一可以很明显看的出来可以使用最值分治,我们可以使用 st 表找到最值的位置,复杂度
code
//Author:Kevin Z K Y
#include <bits/stdc++.h>
#define up(a,b,c) for(int (a)=(b);(a)<=(c);(a)++)
#define dn(a,b,c) for(int (a)=(b);(a)>=(c);(a)--)
#define fst first
#define sed second
using namespace std;
using ll = long long ;using hint = __int128 ;
using pii = pair<int,int> ;using pll = pair<ll,ll> ;
using vi = vector<int> ;using vl = vector<ll> ;
using vpi = vector<pii> ;using vpl = vector<pll> ;
using db = double ;namespace mystl{
#define gc() getchar()
ll qpow(ll a,ll b,const ll&p){if (a==0ll) return 0ll; ll c=1ll;
while(b) { if(b & 1) c=a*c%p; a=a*a%p; b>>=1; } return c; }
template<typename T>void read(T&x) {x=0; bool f=false; char ch;
ch = gc(); while(ch<'0'||ch>'9') f |= ( ch=='-') , ch=gc();
while(ch>='0'&&ch<='9') x=x*10+ch-'0' , ch=gc(); x=f?-x:x;}
template<typename T>void write(T x){char s[40];short d=0;T y=x;
if(x<0) putchar('-'),y=-y;if(x==0){ putchar('0'); return; }
while(y){s[++d]=y%10+'0';y/=10;}while(d>0)putchar(s[d--]);}
template<typename T>void wris(T x,char c){write(x);putchar(c);}
}using namespace mystl;
namespace my{
const int N=100005;
ll a[N];
map<pii,ll>G;
ll f[N][25];
int n,q;
int id[N][25];
void build_st_table(){
up(i,1,n)f[i][0]=a[i],id[i][0]=i;
for(int i=1;(1<<i)<=n;i++)
for(int j=1;j+(1<<i)-1<=n;j++)
if(f[j][i-1]<f[j+(1<<(i-1))][i-1])
f[j][i]=f[j][i-1],id[j][i]=id[j][i-1];
else
f[j][i]=f[j+(1<<(i-1))][i-1],id[j][i]=id[j+(1<<(i-1))][i-1];
}
int query(int l,int r){
int len=(r-l+1);
int kget=log2(r-l+1);
if(f[l][kget]<f[r-(1<<(kget))+1][kget])
return id[l][kget];
else
return id[r-(1<<(kget))+1][kget];
}
ll solve(int l,int r){
if(l>r)return 0;
if(l==r)return a[l];
pii p={l,r};
if(G[p])return G[p];
int pos=query(l,r);
return G[p]=solve(l,pos-1)+solve(pos+1,r)+(pos-l+1)*(r-pos+1)*a[pos];
}
void solve(){
cin>>n>>q;
up(i,1,n)cin>>a[i];
build_st_table();
while(q--){
int L,R;cin>>L>>R;
cout<<solve(L,R)<<'\n';
}
}
}
int main(){
// freopen("","r",stdin);
// freopen("","w",stdout);
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int _=1;while(_--)my::solve();return 0;
}
闲话
这个数据还是非常的逆天,这都能过,确实非常离谱。