• [BZOJ 3681]Ariettad


    终于是打完了 CH 上的数据结构专场了……

    不过看样子还有一套 5555

    传送门: http://ch.ezoj.tk/contest/CH%20Round%20%2351%20-%20Shinrein%E7%A5%AD%20%231

    直接连边会 TLE。但是,连出去的点都是一个连续点集……

    ——于是我们机智的用了 “可合并线段树”(好,) 以空间换取时间

    在网络流的图中塞一棵可持久化线段树进去,这样区间连边时就只会连 O(logn) 的边了

    智商++,而且这道题让我重新认识了线段树的合并,真是受益匪浅~

    不过——

    我恨卡内存!!!

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 const int inf=0x7FFFFFFF;
      5 const int sizeOfSegmemt=4000004;
      6 const int sizeOfEdge=2000002;
      7 const int sizeOfPoint=320032;
      8 const int sizeOfNote=10001;
      9 
     10 int n, m;
     11 int P[sizeOfNote], H[sizeOfNote];
     12 std::vector<int> son[sizeOfPoint];
     13 inline int min(int, int);
     14 inline int getint();
     15 inline void putint(int);
     16 
     17 struct seg {int p; seg * l, * r;};
     18 seg memory_seg[sizeOfSegmemt], * port_seg=memory_seg;
     19 seg * t[sizeOfPoint];
     20 inline seg * newseg();
     21 void insert(seg *& , int, int, int, int);
     22 seg * merge(seg * , seg * );
     23 void query(seg * , int, int, int, int, int);
     24 void dfs(int);
     25 
     26 int S, T;
     27 int V, E;
     28 struct edge {int point, flow; edge * next, * pair;};
     29 edge memory_edge[sizeOfEdge], * port_edge=memory_edge;
     30 edge * e[sizeOfPoint];
     31 int h[sizeOfPoint], gap[sizeOfPoint];
     32 inline edge * newedge(int, int, edge * );
     33 inline void link(int, int, int);
     34 int head, tail, queue[sizeOfPoint];
     35 inline bool bfs();
     36 edge * r[sizeOfPoint], * p[sizeOfPoint];
     37 int aug[sizeOfPoint];
     38 inline int isap();
     39 
     40 int main()
     41 {
     42     int D, L, R, M;
     43 
     44     n=getint(), m=getint();
     45     S=0; T=n+1; V=n+1;
     46     for (int i=2;i<=n;i++)
     47     {
     48         P[i]=getint();
     49         son[P[i]].push_back(i);
     50     }
     51     for (int i=1;i<=n;i++)
     52         H[i]=getint();
     53 
     54     dfs(1);
     55 
     56     for (int i=1;i<=m;i++)
     57     {
     58         L=getint(), R=getint(), D=getint(), M=getint();
     59         link(S, ++V, M);
     60         query(t[D], 1, n, L, R, V);
     61     }
     62 
     63     putint(isap());
     64 
     65     return 0;
     66 }
     67 inline int min(int x, int y)
     68 {
     69     return x<y?x:y;
     70 }
     71 inline int getint()
     72 {
     73     register int num=0;
     74     register char ch;
     75     do ch=getchar(); while (ch<'0' || ch>'9');
     76     do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
     77     return num;
     78 }
     79 inline void putint(int num)
     80 {
     81     char stack[11];
     82     register int top=0;
     83     if (num==0) stack[top=1]='0';
     84     for ( ;num;num/=10) stack[++top]=num%10+'0';
     85     for ( ;top;top--) putchar(stack[top]);
     86     putchar('
    ');
     87 }
     88 inline edge * newedge(int point, int flow, edge * next)
     89 {
     90     edge * ret=port_edge++;
     91     ret->point=point; ret->flow=flow; ret->next=next;
     92     return ret;
     93 }
     94 inline void link(int u, int v, int f)
     95 {
     96     e[u]=newedge(v, f, e[u]); e[v]=newedge(u, 0, e[v]);
     97     e[u]->pair=e[v]; e[v]->pair=e[u];
     98 }
     99 inline bool bfs()
    100 {
    101     memset(h, 0xFF, sizeof(h)); h[T]=0;
    102     head=tail=0;
    103     for (queue[tail++]=T;head<tail;head++)
    104     {
    105         int u=queue[head];
    106         gap[h[u]]++;
    107         for (edge * i=e[u];i;i=i->next) if (h[i->point]==-1)
    108         {
    109             h[i->point]=h[u]+1;
    110             queue[tail++]=i->point;
    111         }
    112     }
    113     return h[S]>-1;
    114 }
    115 inline int isap()
    116 {
    117     int flow=0;
    118     int hmin=0;
    119 
    120     if (!bfs()) return 0;
    121 
    122     memcpy(r, e, sizeof(e));
    123     memset(p, 0, sizeof(p));
    124     aug[S]=inf;
    125     for (int u=S;h[S]<V; )
    126     {
    127         if (u==T)
    128         {
    129             flow+=aug[T];
    130             for (edge * i=p[T];i;i=p[i->point])
    131                 i->pair->flow-=aug[T], i->flow+=aug[T], aug[i->point]-=aug[T];
    132             for (edge * i=p[T];i;i=p[i->point]) if (aug[i->point])
    133             {
    134                 u=i->point;
    135                 break;
    136             }
    137         }
    138 
    139         edge *& i=r[u];
    140         for ( ;i && (!i->flow || h[i->point]+1!=h[u]);i=i->next);
    141         if (i)
    142         {
    143             p[i->point]=i->pair; aug[i->point]=min(aug[u], i->flow);
    144             u=i->point;
    145         }
    146         else
    147         {
    148             if (!--gap[h[u]]) break;
    149             hmin=V;
    150             for (edge * j=e[u];j;j=j->next) if (j->flow && h[j->point]+1<hmin)
    151             {
    152                 r[u]=j;
    153                 hmin=h[j->point]+1;
    154             }
    155             ++gap[h[u]=hmin];
    156             u=u==S?S:p[u]->point;
    157         }
    158     }
    159 
    160     return flow;
    161 }
    162 
    163 inline seg * newseg()
    164 {
    165     seg * ret=port_seg++;
    166     ret->p=++V; ret->l=ret->r=NULL;
    167     return ret;
    168 }
    169 void insert(seg *& t, int l, int r, int p, int v)
    170 {
    171     if (!t) t=newseg();
    172     if (l==r) link(t->p, v, inf);
    173     else
    174     {
    175         int m=(l+r)>>1;
    176         if (p<=m) insert(t->l, l, m, p, v), link(t->p, t->l->p, inf);
    177         else insert(t->r, m+1, r, p, v), link(t->p, t->r->p, inf);
    178     }
    179 }
    180 seg * merge(seg * x, seg * y)
    181 {
    182     if (!x) return y;
    183     if (!y) return x;
    184     seg * t=newseg();
    185     bool leaf=true;
    186     if ((t->l=merge(x->l, y->l))) link(t->p, t->l->p, inf), leaf=false;
    187     if ((t->r=merge(x->r, y->r))) link(t->p, t->r->p, inf), leaf=false;
    188     if (leaf) link(t->p, x->p, inf), link(t->p, y->p, inf);
    189     return t;
    190 }
    191 void query(seg * t, int l, int r, int ql, int qr, int p)
    192 {
    193     if (!t) return ;
    194     if (l==ql && r==qr) link(p, t->p, inf);
    195     else
    196     {
    197         int m=(l+r)>>1;
    198         if (qr<=m) query(t->l, l, m, ql, qr, p);
    199         else if (ql>=m+1) query(t->r, m+1, r, ql, qr, p);
    200         else query(t->l, l, m, ql, m, p), query(t->r, m+1, r, m+1, qr, p);
    201     }
    202 }
    203 void dfs(int u)
    204 {
    205     link(u, T, 1);
    206     insert(t[u], 1, n, H[u], u);
    207     for (unsigned int i=0;i<son[u].size();i++)
    208     {
    209         dfs(son[u][i]);
    210         t[u]=merge(t[u], t[son[u][i]]);
    211     }
    212 }
    我恨卡内存++
  • 相关阅读:
    实现自己的Linq to Sql
    [分享] 浅谈项目需求变更管理
    【分享】老程序员的经验和价值在哪里?
    程序员是自己心中的“上帝”
    [分享]解析“程序员的十大技术烦恼”
    【分享】帮助你早些明白一些道理
    “风雨20年”的20条精辟编程经验
    【分享】 优秀程序员的代码是“活的”
    给开发人员培训时的语录
    【分享】SQL Server优化50法
  • 原文地址:https://www.cnblogs.com/dyllalala/p/4141119.html
Copyright © 2020-2023  润新知