zoukankan      html  css  js  c++  java
  • 分治模板

    meet in the middlehttps://www.lydsy.com/JudgeOnline/problem.php?id=4800

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1.1e6;
    int n,len;
    ll ans,m,n1,n2,c[50],a[N],b[N];
    void dfs1(int u,ll s)
    {
        if(s>m)return;
        if(u==len+1){a[++n1]=s;return;}
        dfs1(u+1,s),dfs1(u+1,s+c[u]);
    }
    void dfs2(int u,ll s)
    {
        if(s>m)return;
        if(u==n+1){b[++n2]=s;return;}
        dfs2(u+1,s),dfs2(u+1,s+c[u]);
    }
    int main()
    {
        scanf("%d%lld",&n,&m),len=n>>1;
        for(int i=1;i<=n;i++)scanf("%lld",&c[i]);
        dfs1(1,0),dfs2(len+1,0);
        sort(a+1,a+n1+1);
        sort(b+1,b+n2+1);
        for(int i=1,j=n2;i<=n1;i++)
        {
            while(a[i]+b[j]>m)j--;
            ans+=j;
        }
        printf("%lld",ans);
    }

    CDQ分治https://www.luogu.org/problemnew/show/P3810

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+7;
    struct node{int x,y,z,cnt,ans;}a[N];
    int n,k,tot,C[N*2],num[N];
    bool cmp(node a,node b)
    {
        if(a.x==b.x)return a.y==b.y?a.z<b.z:a.y<b.y;
        return a.x<b.x;
    }
    bool dmp(node a,node b)
    {
        if(a.y==b.y)return a.x==b.x?a.z<b.z:a.x<b.x;
        return a.y<b.y;
    }
    void update(int x,int v){while(x<=k)C[x]+=v,x+=x&-x;}
    int query(int x){int ret=0;while(x)ret+=C[x],x-=x&-x;return ret;}
    void cdq(int l,int r)
    {
        if(l==r){a[l].ans+=a[l].cnt-1;return;}
        int mid=(l+r)/2;
        cdq(l,mid);cdq(mid+1,r);
        sort(a+l,a+mid+1,dmp),sort(a+mid+1,a+r+1,dmp);
        int j=l;
        for(int i=mid+1;i<=r;i++)
        {
            while(j<=mid&&a[j].y<=a[i].y)update(a[j].z,a[j].cnt),j++;
            a[i].ans+=query(a[i].z);
        }
        for(int i=l;i<j;i++)update(a[i].z,-a[i].cnt);
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
        sort(a+1,a+n+1,cmp);
        a[tot=1].cnt=1;
        for(int i=2;i<=n;i++)
        if(a[i].x==a[i-1].x&&a[i].y==a[i-1].y&&a[i].z==a[i-1].z)a[tot].cnt++;
        else a[++tot]=a[i],a[tot].cnt=1;
        cdq(1,tot);
        sort(a+1,a+tot+1,cmp);
        for(int i=1;i<=tot;i++)num[a[i].ans]+=a[i].cnt;
        for(int i=0;i<n;i++)printf("%d
    ",num[i]);
    }

    点分治https://www.lydsy.com/JudgeOnline/problem.php?id=1468

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=41000;
    struct edge{int v,nxt,w;}e[N*2];
    int n,k,sz[N],mx[N],head[N],d[N],a[N],top,cnt,root,ans;
    bool vis[N];
    void add(int u,int v,int w)
    {e[++cnt]=(edge){v,head[u],w};head[u]=cnt;}
    void dfs(int u,int fa)
    {
        sz[u]=1;
        for(int i=head[u];i;i=e[i].nxt)
        if(e[i].v!=fa&&!vis[e[i].v])
        {
            dfs(e[i].v,u);
            sz[u]+=sz[e[i].v];
            mx[u]=max(mx[u],sz[e[i].v]);
        }
        mx[u]=max(mx[u],n-sz[u]);
        if(mx[u]<mx[root])root=u;
    }
    void getd(int u,int fa)
    {
        a[++top]=d[u];
        for(int i=head[u];i;i=e[i].nxt)
        if(e[i].v!=fa&&!vis[e[i].v])
        {
            d[e[i].v]=d[u]+e[i].w;
            getd(e[i].v,u);
        }
    }
    int cal(int u,int x)
    {
        d[u]=x;
        top=0;getd(u,0);
        sort(a+1,a+top+1);
        int ret=0,l=1,r=top;
        while(l<r)
        if(a[l]+a[r]<=k){ret+=r-l;l++;}else r--;
        return ret;
    }
    void solve(int u)
    {
        ans+=cal(u,0);
        vis[u]=1;
        for(int i=head[u];i;i=e[i].nxt)
        if(!vis[e[i].v])
        {
            ans-=cal(e[i].v,e[i].w);
            root=0;
            dfs(e[i].v,0);
            solve(root);
        }
    }
    int main()
    {
        scanf("%d",&n);
        mx[0]=n;
        int x,y,z;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);add(y,x,z);
        }
        scanf("%d",&k);
        dfs(1,0);
        solve(root);
        printf("%d",ans);
    }

    动态点分治https://www.luogu.org/problemnew/show/P3241

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int N=1.5e5+7,M=4e5+7;
    struct node{int x,d;}p[N<<5];
    int n,m,A,num,all,rt,tot,a[N],hd[N],v[M],nxt[M],w[M],sz[N],fa[N];
    int L[N][3],R[N][3],cnt[N],son[N][3],in[N<<1],dfn[N<<1],dep[N],lg[N<<1],f[N<<1][18],sum[N];
    ll ans,pre[N<<5];
    bool vis[N];
    void add(int x,int y,int z){v[++num]=y,w[num]=z,nxt[num]=hd[x],hd[x]=num;}
    bool cmp(node x,node y){return a[x.x]<a[y.x];}
    void getsz(int u,int fa)
    {
        sz[u]=1;
        for(int i=hd[u];i;i=nxt[i])if(v[i]!=fa&&!vis[v[i]])getsz(v[i],u),sz[u]+=sz[v[i]];
    }
    void findroot(int u,int fa)
    {
        int mx=0;
        for(int i=hd[u];i;i=nxt[i]) 
        if(v[i]!=fa&&!vis[v[i]])findroot(v[i],u),mx=max(mx,sz[v[i]]);
        mx=max(mx,all-sz[u]);
        if(mx<=all/2)rt=u;
    }
    void dfs(int u,int fa,int d)
    {
        p[++tot]=(node){u,d};
        for(int i=hd[u];i;i=nxt[i])if(!vis[v[i]]&&v[i]!=fa)dfs(v[i],u,d+w[i]);
    }
    int solve(int u,int f)
    {
        getsz(u,0),all=sz[u],findroot(u,0);
        int now=rt;
        for(int i=hd[now];i;i=nxt[i])
        if(!vis[v[i]])L[now][cnt[now]]=tot+1,dfs(v[i],now,w[i]),R[now][cnt[now]++]=tot;
        int ret=0;vis[now]=1,fa[now]=f;
        for(int i=hd[now];i;i=nxt[i])if(!vis[v[i]])son[now][ret++]=solve(v[i],now);
        return now;
    }
    void dfs2(int x,int fa)
    {
        in[x]=++num,dfn[num]=x,dep[x]=dep[fa]+1;
        for(int i=hd[x];i;i=nxt[i])
        if(v[i]!=fa)sum[v[i]]=sum[x]+w[i],dfs2(v[i],x),dfn[++num]=x;
    }
    int lca(int x,int y)
    {
        x=in[x],y=in[y];if(x>y)swap(x,y);
        int k=lg[y-x+1];
        return (dep[f[x][k]]<dep[f[y-(1<<k)+1][k]])?f[x][k]:f[y-(1<<k)+1][k];
    }
    int find(int l,int r,int v)
    {
        int mid;r++;
        while(l<r)
        {
            mid=l+r>>1;
            (a[p[mid].x]<=v)?l=mid+1:r=mid;
        }
        return l-1;
    }
    ll query(int x,int v)
    {
        ll ret=0;
        for(int lst=0,i=x;i;lst=i,i=fa[i])
        {
            int D=sum[x]+sum[i]-2*sum[lca(x,i)],pos;
            ret+=(a[i]<=v)*D;
            for(int j=0;j<cnt[i];j++)
            if(son[i][j]!=lst)
            pos=find(L[i][j],R[i][j],v),ret+=1ll*(pos-L[i][j]+1)*D+pre[pos]-pre[L[i][j]-1];
        }
        return ret;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&A);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1,x,y,z;i<n;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
        solve(1,0);
        for(int i=1;i<=n;i++)
        for(int j=0;j<cnt[i];j++)
        sort(p+L[i][j],p+R[i][j]+1,cmp);
        for(int i=1;i<=tot;i++)pre[i]=pre[i-1]+p[i].d;
        num=0,dfs2(1,0),lg[0]=-1;
        for(int i=1;i<=num;i++)f[i][0]=dfn[i],lg[i]=lg[i>>1]+1;
        for(int j=1;j<=17;j++)
        for(int i=1;i<=num-(1<<j);i++)
        f[i][j]=(dep[f[i][j-1]]<dep[f[i+(1<<j-1)][j-1]])?f[i][j-1]:f[i+(1<<j-1)][j-1];
        while(m--)
        {
            int x,l,r;scanf("%d%d%d",&x,&l,&r);
            l=(l+ans)%A,r=(r+ans)%A;
            if(l>r)swap(l,r);
            printf("%lld
    ",ans=query(x,r)-query(x,l-1));
        }
    }

    线段树分治https://www.luogu.org/problemnew/show/P4585

    #include<bits/stdc++.h>
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    using namespace std;
    const int N=1e5+7;
    struct guest{int l,r,L,R,x;}p[N];
    struct buy{int s,v,t;}q[N],t1[N],t2[N];
    int n,m,n1,n2,tot,top,rt[N],ans[N],st[N],ch[N*19][2],sz[N*19];
    vector<int>a[N];
    bool cmp(buy x,buy y){return x.s<y.s;}
    void build(int&x,int u,int S)
    {
        x=++tot;
        int now=x;
        for(int i=17;~i;i--)
        {
            bool d=S>>i&1;
            ch[now][d^1]=ch[u][d^1],ch[now][d]=++tot;
            now=ch[now][d],u=ch[u][d],sz[now]=sz[u]+1;
        }
    }
    int query(int l,int r,int S)
    {
        int ret=0;
        for(int i=17;~i;i--)
        {
            bool d=S>>i&1;
            if(sz[ch[r][d^1]]-sz[ch[l][d^1]]>0)l=ch[l][d^1],r=ch[r][d^1],ret+=1<<i;
            else l=ch[l][d],r=ch[r][d];
        }
        return ret;
    }
    void update(int L,int R,int x,int l,int r,int rt)
    {
        if(L>R)return;
        if(L<=l&&r<=R){a[rt].push_back(x);return;}
        int mid=l+r>>1;
        if(L<=mid)update(L,R,x,lson);
        if(R>mid)update(L,R,x,rson);
    }
    void calc(int x,int L,int R)
    {
        top=tot=0;
        for(int i=L;i<=R;i++)st[++top]=q[i].s,build(rt[top],rt[top-1],q[i].v);
        for(int i=0,k,l,r;i<a[x].size();i++)
        {
            k=a[x][i];
            l=upper_bound(st+1,st+top+1,p[k].l-1)-st-1,r=upper_bound(st+1,st+1+top,p[k].r)-st-1;
            ans[k]=max(ans[k],query(rt[l],rt[r],p[k].x));
        }
    }
    void divide(int l,int r,int rt,int L,int R)
    {
        if(L>R)return;
        int mid=l+r>>1,cnt1=0,cnt2=0;
        calc(rt,L,R);
        if(l==r)return;
        for(int i=L;i<=R;i++)if(q[i].t<=mid)t1[++cnt1]=q[i];else t2[++cnt2]=q[i];
        for(int i=1;i<=cnt1;i++)q[i+L-1]=t1[i];
        for(int i=1;i<=cnt2;i++)q[i+L-1+cnt1]=t2[i];
        divide(lson,L,L+cnt1-1);
        divide(rson,L+cnt1,R);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x;i<=n;i++)scanf("%d",&x),build(rt[i],rt[i-1],x);
        for(int i=1,op,l,r,x,d;i<=m;i++)
        {
            scanf("%d%d%d",&op,&l,&r);
            if(!op)q[++n1]=(buy){l,r,n1};
            else{
                scanf("%d%d",&x,&d);
                ans[++n2]=query(rt[l-1],rt[r],x);
                p[n2]=(guest){l,r,max(1,n1-d+1),n1,x};
            }
        }
        for(int i=1;i<=n2;i++)update(p[i].L,p[i].R,i,1,n1,1);
        sort(q+1,q+n1+1,cmp);
        divide(1,n1,1,1,n1);
        for(int i=1;i<=n2;i++)printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    MySQL for OPS 02:SQL 基础
    Samba:基于公网 IP 的服务访问
    MySQL for OPS 01:简介 / 安装初始化 / 用户授权管理
    Samba:打造企业级授权文件共享服务器
    嵌入式web server——Goahead移植要点
    libConfuse的使用
    【工具篇】notepad++
    使用sprintf打印float并控制小数位数时引起的问题
    【工具篇】source Insight
    【工具篇】xshell
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/11039159.html
Copyright © 2011-2022 走看看