zoukankan      html  css  js  c++  java
  • PTA L3-026 传送门 (splay) (2020团体程序设计天梯赛)

    题目链接

    快住手,这不是ACM!!!

    将所有需要添加或者删除的传送门的y值离散化,一开始初始化成n条链,传送门对应链上的结点。对于每个操作,实际上要做的是“分别查询两个结点各自所在链上的左右端点”和“将两个结点的后继结点交换”,用splay可以做到$O(log(q))$时间修改和查询。添加和删除传送门的操作其实是等价的,因此前面的"+"和"-"可以无视

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef double db;
     5 const int N=5e5+10,inf=0x3f3f3f3f;
     6 int n,m,fa[N],ch[N][2],tot,X[N];
     7 ll ans;
     8 #define l(u) ch[u][0]
     9 #define r(u) ch[u][1]
    10 int sf(int u) {return u==r(fa[u]);}
    11 bool isrt(int u) {return u!=l(fa[u])&&u!=r(fa[u]);}
    12 void rot(int u) {
    13     int v=fa[u],f=sf(u);
    14     if(!isrt(v))ch[fa[v]][sf(v)]=u;
    15     ch[v][f]=ch[u][f^1],fa[ch[v][f]]=v;
    16     fa[u]=fa[v],ch[u][f^1]=v,fa[v]=u;
    17 }
    18 int newnode() {int u=++tot; fa[u]=l(u)=r(u)=0; return u;}
    19 void splay(int u) {for(; !isrt(u); rot(u))if(!isrt(fa[u])&&sf(fa[u])==sf(u))rot(fa[u]);}
    20 int fdl(int u) {splay(u); for(; l(u); u=l(u)); splay(u); return u;}
    21 int fdr(int u) {splay(u); for(; r(u); u=r(u)); splay(u); return u;}
    22 struct QR {int x1,x2,y1,y2;} qr[N];
    23 vector<int> rt[N];
    24 
    25 int main() {
    26     scanf("%d%d",&n,&m);
    27     for(int i=1; i<=m; ++i)scanf(" %*c%d%d%d",&qr[i].x1,&qr[i].x2,&qr[i].y1);
    28     for(int i=1; i<=n; ++i)rt[i].push_back(0),rt[i].push_back(inf);
    29     for(int i=1; i<=m; ++i)rt[qr[i].x1].push_back(qr[i].y1),rt[qr[i].x2].push_back(qr[i].y1);
    30     for(int i=1; i<=n; ++i) {
    31         sort(rt[i].begin(),rt[i].end());
    32         rt[i].resize(unique(rt[i].begin(),rt[i].end())-rt[i].begin());
    33     }
    34     for(int i=1; i<=m; ++i) {
    35         int y=qr[i].y1;
    36         qr[i].y1=lower_bound(rt[qr[i].x1].begin(),rt[qr[i].x1].end(),y)-rt[qr[i].x1].begin();
    37         qr[i].y2=lower_bound(rt[qr[i].x2].begin(),rt[qr[i].x2].end(),y)-rt[qr[i].x2].begin();
    38     }
    39     for(int i=1; i<=n; ++i) {
    40         for(int j=0; j<rt[i].size(); ++j)rt[i][j]=newnode(),X[rt[i][j]]=i;
    41         for(int j=0; j<rt[i].size()-1; ++j)r(rt[i][j])=rt[i][j+1],fa[rt[i][j+1]]=rt[i][j];
    42     }
    43     ans=(ll)n*(n+1)*(2*n+1)/6;
    44     for(int i=1; i<=m; ++i) {
    45         int x1=qr[i].x1,x2=qr[i].x2,y1=qr[i].y1,y2=qr[i].y2;
    46         int u=rt[x1][y1],v=rt[x2][y2];
    47         int lu=X[fdl(u)],ru=X[fdr(u)],lv=X[fdl(v)],rv=X[fdr(v)];
    48         ans-=(ll)lu*ru+(ll)lv*rv;
    49         ans+=(ll)lu*rv+(ll)lv*ru;
    50         splay(u),splay(v);
    51         int u2=r(u),v2=r(v);
    52         r(u)=v2,r(v)=u2,fa[v2]=u,fa[u2]=v;
    53         printf("%lld
    ",ans);
    54     }
    55     return 0;
    56 }

    场上暴力水了十几分,菜菜菜

  • 相关阅读:
    数据结构进阶——线段树
    基本数据结构—Hash哈希
    NOIP2013提高组 day2 2019.7.15
    基本算法——归并排序
    基本数据结构—Trie
    NOIP 2011 提高组 Day2 校模拟 7.11
    Noip2014提高组真题Day1,2 校模拟7.7
    NOIP2015 提高组 day1 7.8校模拟
    NOIP2008 提高组 6.9校模拟
    STL-#include<set>
  • 原文地址:https://www.cnblogs.com/asdfsag/p/14139528.html
Copyright © 2011-2022 走看看