• CF1140F Extending Set of Points


    Link
    不难发现扩展完之后,所有的点构成了若干个不相交的表格状的图形。
    对于每条边,它有一些出现的时间区间。
    因此我们线段树分治,利用并查集维护答案。
    注意到需要撤销,因此必须使用不带路径压缩的按秩合并。

    #include<map>
    #include<stack>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<numeric>
    #include<utility>
    #include<algorithm>
    #define fi first
    #define se second
    using i64=long long;
    using pi=std::pair<int,int>;
    int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
    const int N=600007;
    std::map<pi,int>mp;std::vector<pi>e[N<<2];
    int m,fa[N],sizex[N],sizey[N];i64 ans;
    int find(int x){return x==fa[x]? x:find(fa[x]);}
    #define ls p<<1
    #define rs p<<1|1
    #define mid ((l+r)>>1)
    void update(int p,int l,int r,int L,int R,pi x)
    {
        if(l>R||L>r) return ;
        if(L<=l&&r<=R) return e[p].push_back(x);
        update(ls,l,mid,L,R,x),update(rs,mid+1,r,L,R,x);
    }
    void merge(int x,int y,std::stack<int>&stk)
    {
        if((x=find(x))==(y=find(y))) return ;
        if(sizex[x]+sizey[x]<sizex[y]+sizey[y]) std::swap(x,y);
        ans-=1ll*sizex[x]*sizey[x]+1ll*sizex[y]*sizey[y],fa[y]=x,sizex[x]+=sizex[y],sizey[x]+=sizey[y],ans+=1ll*sizex[x]*sizey[x],stk.push(y);
    }
    void solve(int p,int l ,int r)
    {
        i64 temp=ans;std::stack<int>stk;
        for(auto x:e[p]) merge(x.fi,x.se+300000,stk);
        if(l==r) printf("%lld ",ans); else solve(ls,l,mid),solve(rs,mid+1,r);
        for(int x,y;!stk.empty();) x=stk.top(),stk.pop(),y=find(x),sizex[y]-=sizex[x],sizey[y]-=sizey[x],fa[x]=x;
        ans=temp;
    }
    #undef ls
    #undef rs
    #undef mid
    int main()
    {
        m=read();
        for(int i=1,x,y;i<=m;++i) if(mp.find({x=read(),y=read()})==mp.end()) mp[{x,y}]=i; else update(1,1,m,mp[{x,y}],i-1,{x,y}),mp.erase(mp.find({x,y}));
        for(auto t:mp) update(1,1,m,t.se,m,t.fi);
        std::iota(fa+1,fa+600001,1),std::fill(sizex+1,sizex+300001,1),std::fill(sizey+300001,sizey+600001,1),solve(1,1,m);
    }
    
  • 相关阅读:
    LeetCode OJ:Divide Two Integers(两数相除)
    LeetCode OJ:Sqrt(x)(平方根)
    LeetCode OJ:Excel Sheet Column Number(表格列数)
    LeetCode OJ:Compare Version Numbers(比较版本字符串)
    LeetCode OJ:Valid Parentheses(有效括号)
    LeetCode OJ:Longest Common Prefix(最长公共前缀)
    LeetCode OJ:Linked List Cycle II(循环链表II)
    LeetCode OJ:Permutations II(排列II)
    LeetCode OJ:Permutations(排列)
    MongoDB复制二:复制集的管理
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12445481.html
Copyright © 2020-2023  润新知