zoukankan      html  css  js  c++  java
  • 洛谷P2611 [ZJOI2012]小蓝的好友

    总子矩形个数减去内部没有资源点的子矩形个数即为答案。

    考虑枚举子矩形的下边界,从上到下进行扫描。对列建笛卡尔树,其中序遍历为下标,维护堆性质的权值为该列上点的行数最大值。然后在笛卡尔树上的每个节点统计贡献。

    扫描时需要支持单点修改权值,那么直接用 (FHQ Treap) 建笛卡尔树即可,因为数据随机,所以复杂度有保证。

    #include<bits/stdc++.h>
    #define maxn 200010
    using namespace std;
    typedef long long ll;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,m,k,tot,root;
    int ls[maxn],rs[maxn],val[maxn],siz[maxn];
    ll ans;
    ll key[maxn],sum[maxn];
    vector<int> ve[maxn];
    void pushup(int x)
    {
        siz[x]=siz[ls[x]]+siz[rs[x]]+1;
        sum[x]=sum[ls[x]]+sum[rs[x]]+key[x]*(siz[ls[x]]+1)*(siz[rs[x]]+1);
    }
    void build(int l,int r,int &x)
    {
        int mid=(l+r)>>1;
        x=++tot,siz[x]=1,val[x]=mid;
        if(l<mid) build(l,mid-1,ls[x]);
        if(r>mid) build(mid+1,r,rs[x]);
        pushup(x);
    }
    void merge(int &p,int x,int y)
    {
        if(!x||!y)
        {   
            p=x+y;
            return;
        }
        if(key[x]>key[y]) p=x,merge(rs[p],rs[p],y);
        else p=y,merge(ls[p],x,ls[p]);
        pushup(p);
    }
    void split(int p,int k,int &x,int &y)
    {
        if(!p)
        {
            x=y=0;
            return;
        }
        if(val[p]<=k) x=p,split(rs[p],k,rs[p],y);
        else y=p,split(ls[p],k,x,ls[p]);
        pushup(p);
    }
    void modify(int k,int v)
    {
        int x,y,z;
        split(root,k,x,y),split(x,k-1,x,z);
        key[z]=v,pushup(z),merge(x,x,z),merge(root,x,y);
    }
    int main()
    {
        read(n),read(m),read(k),build(1,m,root);
        for(int i=1;i<=k;++i)
        {
            int x,y;
            read(x),read(y),ve[x].push_back(y);
        }
        for(int i=1;i<=n;++i)
        {
            for(int j=0;j<ve[i].size();++j) modify(ve[i][j],i);
            ans+=(ll)i*m*(m+1)/2-sum[root];
        }
        printf("%lld",(ll)n*(n+1)/2*m*(m+1)/2-ans);
        return 0;
    }
    
  • 相关阅读:
    毕设2020.02.02
    架构师眼中的高并发架构
    云时代架构读后感二
    以《淘宝网》为例,描述质量属性六个常见场景
    《架构漫谈》读后感
    云时代架构读后感一
    暑假周总结报告08
    暑假周总结报告07
    暑假周总结报告06
    假期周总结报告05
  • 原文地址:https://www.cnblogs.com/lhm-/p/13907923.html
Copyright © 2011-2022 走看看