Luogu P4755美しいペア(最大パーティション)

表題の
前処理\(L [P]は\)の数プラス1に等しく、その左側の位置の最初のより大きい値を表す\(R&LT [P] \)の数の最初の位置の右以上の値を示し、そのマイナス1。
ために考慮する\(P \)の最大値\(P \)間隔の\([L [P]は、R [P]] \) すなわち、左端点\([L [P]、 P] \)で、右端\([P、R&LT [P]] \)
私たちは、小さなの長さの期間を取ります。
例えば、\([L [P]、 P] \) これはかなり短いので、\(\ FORALL私が\ [L [P-]は、P-] \) 答えが追加される\([P、R [Pを] \)以上の\(\ lfloorの\のFRAC { [P]} {[I]} \ rfloor \) カウント数の。
その撥に受信\([1、Rは、[P ]] \) よりも大きい\(\ lfloorの\のFRAC { [P]} {[I]} \ rfloor \) の値マイナスの数\([1、P-1 ] \) 以上の\(\ lfloorの\のFRAC { [P]} {[I]} \ rfloor \)番号の数。
場合\([P、R [pは ] \) 同じ操作を行うことが比較的短いです。
以上ではないの複雑なことを示すことができる\(N-の\ \ nlog)
私たちは、離散した後、フェンウィックツリーのメンテナンスを使用することにしました。

#include<bits/stdc++.h>
#define P pair<int,int>
#define mp make_pair
#define fir first
#define sec second
#define pb push_back
#define LL long long
using namespace std;
const int N=100007;
int a[N],t[N],L[N],R[N],n,m;
LL s[N];
P stk[N];
vector<int>vec[N];
int abs(int a){return a<0? -a:a;}
int read(){int x;scanf("%d",&x);return x;}
int lowbit(int x){return x&-x;}
int Find(int x){return x>=t[n]? n:upper_bound(t+1,t+m+1,x)-(t+1);}
LL query(int x)
{
    LL sum=0;
    while(x) sum+=s[x],x-=lowbit(x);
    return sum;
}
void update(int x,int v){while(x<=n)s[x]+=v,x+=lowbit(x);}
int main()
{
    n=read();int i,j,top;LL ans=0;
    for(i=1;i<=n;++i) a[i]=t[i]=read();
    for(i=1,top=0;i<=n;++i)
    {
    while(top&&stk[top].fir<a[i]) --top;
    L[i]=(top? stk[top].sec+1:1),stk[++top]=mp(a[i],i);
    }
    for(i=n,top=0;i;--i)
    {
    while(top&&stk[top].fir<=a[i]) --top;
    R[i]=(top? stk[top].sec-1:n),stk[++top]=mp(a[i],i);
    }
    for(i=1;i<=n;++i)
    if(i-L[i]<=R[i]-i) for(vec[i-1].pb(-1),vec[R[i]].pb(1),j=L[i];j<i;++j) vec[i-1].pb(-a[i]/a[j]),vec[R[i]].pb(a[i]/a[j]);
        else for(vec[L[i]-1].pb(-1),vec[i].pb(1),j=i+1;j<=R[i];++j) vec[L[i]-1].pb(-a[i]/a[j]),vec[i].pb(a[i]/a[j]);
    sort(t+1,t+n+1),m=unique(t+1,t+n+1)-(t+1);
    for(i=1;i<=n;++i) a[i]=lower_bound(t+1,t+m+1,a[i])-t;
    for(i=1;i<=n;i++) for(update(a[i],1),top=vec[i].size(),j=0;j<top;++j) vec[i][j]<0? ans-=query(Find(abs(vec[i][j]))):ans+=query(Find(abs(vec[i][j])));
    return !printf("%lld",ans);
}

おすすめ

転載: www.cnblogs.com/cjoierShiina-Mashiro/p/11512299.html