zoukankan      html  css  js  c++  java
  • 洛谷$P4755 Beautiful Pair$ 最大值分治

    正解:最大值分治

    解题报告:

    传送门$QwQ$

    昂考虑如果已经钦定了点$x$是这个$max$了,然后现在要求有多少对$[l,r]$满足$a_x=maxleft{a_i ight},iin[l,r]$,且$a_lcdot a_rleq a_x$

    现在枚举$l$,发现$r$就有一个范围了,就$a_rleq frac{a_x}{a_l}$,这个就可以用主席树维护下就成嘛$QwQ$(我开始想用树状数组的,,,然后想了下发现因为是分治所以每次树状数组都要重建复杂度是错的$kk$,所以还是去用主席树趴$QwQ$

    所以就基本上能得出这题的基本思路了?首先找到区间最大值$x$,先分别求出$x$两侧的答案,然后统计跨过$x$的贡献.考虑枚举$l$,然后对于$r$就直接树状数组搞下就行.但是发现如果$l$中的点太多也不可,所以考虑枚举$size$较小的那一边.

    这个的复杂度和启发式合并的复杂度是一样的,就$O(nlogn)$,然后加上树状数组的复杂度,总复杂度就两个$log$的

    $over$?

     

    #include<bits/stdc++.h>
    using namespace std;
    #define il inline
    #define gc getchar()
    #define mp make_pair
    #define int long long
    #define ri register int
    #define rc register char
    #define rb register bool
    #define rp(i,x,y) for(ri i=x;i<=y;++i)
    #define my(i,x,y) for(ri i=x;i>=y;--i)
    #define lb(x) lower_bound(b+1,b+1+num,x)-b
    #define ub(x) upper_bound(b+1,b+1+num,x)-b
    
    const int N=1e5+10;
    int n,a[N],b[N],st[20][N],num,rt[N],nod_cnt,lg[N];
    struct node{int num,ls,rs;}tr[N*64];
    
    il int read()
    {
        rc ch=gc;ri x=0;rb y=1;
        while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
        if(ch=='-')ch=gc,y=0;
        while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
        return y?x:-x;
    }
    il int cmp(ri gd,ri gs){return a[gd]>=a[gs]?gd:gs;}
    il void pre()
    {
        lg[0]=-1;rp(i,1,n)st[0][i]=i,lg[i]=lg[i>>1]+1;
        rp(i,1,lg[n])
            rp(j,1,n-(1<<i)+1)st[i][j]=cmp(st[i-1][j],st[i-1][j+(1<<(i-1))]);
    }
    il int ask(ri l,ri r){ri len=lg[r-l+1];return cmp(st[len][l],st[len][r-(1<<len)+1]);}
    int modify(ri nw,ri l,ri r,ri to)
    {
        ri x=++nod_cnt;tr[x]=tr[nw];++tr[x].num;if(l==r)return x;
        ri mid=(l+r)>>1;to<=mid?tr[x].ls=modify(tr[nw].ls,l,mid,to):tr[x].rs=modify(tr[nw].rs,mid+1,r,to);
        return x;
    }
    int query(ri nw,ri l,ri r,ri to)
    {
        if(r<=to)return tr[nw].num;
        ri mid=(l+r)>>1,ret=query(tr[nw].ls,l,mid,to);
        if(mid<to)ret+=query(tr[nw].rs,mid+1,r,to);
        return ret;
    }
    int solv(ri l,ri r)
    {
        if(l>r)return 0;
        if(l==r)return b[a[l]]==1;
        ri mid=ask(l,r),sum=0;sum+=solv(l,mid-1);sum+=solv(mid+1,r);//printf("l=%d r=%d sum=%d mid=%d solv(%d,%d),solv(%d,%d)
    ",l,r,sum,mid,l,mid-1,mid+1,r);
        ri tl=l,tr=mid,askl=mid,askr=r;if(mid-l+1>r-mid)swap(tl,askl),swap(tr,askr);
        //printf("tl=%d tr=%d askl=%d askr=%d
    ",tl,tr,askl,askr);
        rp(i,tl,tr)
        {
            ri lim=ub(b[a[mid]]/b[a[i]])-1;if(lim)sum+=query(rt[askr],1,num,lim)-query(rt[askl-1],1,num,lim);
        }
        //printf("l=%d r=%d sum=%d
    ",l,r,sum);
        return sum;
    }
    
    signed main()
    {
        //freopen("4755.in","r",stdin);freopen("4755.out","w",stdout);
        n=read();rp(i,1,n)a[i]=b[i]=read();sort(b+1,b+1+n);num=unique(b+1,b+1+n)-b-1;
        rp(i,1,n)a[i]=lb(a[i]),rt[i]=modify(rt[i-1],1,num,a[i]);
        pre();printf("%lld
    ",solv(1,n));
        return 0;
    }
    View Code

     

  • 相关阅读:
    Working with macro signatures
    Reset and Clear Recent Items and Frequent Places in Windows 10
    git分支演示
    The current .NET SDK does not support targeting .NET Core 2.1. Either target .NET Core 2.0 or lower, or use a version of the .NET SDK that supports .NET Core 2.1.
    Build website project by roslyn through devenv.com
    Configure environment variables for different tools in jenkins
    NUnit Console Command Line
    Code Coverage and Unit Test in SonarQube
    头脑王者 物理化学生物
    头脑王者 常识,饮食
  • 原文地址:https://www.cnblogs.com/lqsukida/p/11494906.html
Copyright © 2011-2022 走看看