zoukankan      html  css  js  c++  java
  • bzoj 3924 点分

    感谢asm.Definer清楚明了的题解:

    http://www.cnblogs.com/Asm-Definer/p/4470112.html

    收获:

      1.  关于重心, 对于一个无向图, 我们这样给每条边重新确定方向: u<->v这条边将原图分成两个部分Su,Sv,w(S)表示S集合中点的权值和,那么

         u->v 当 w(Su)<w(Sv)

         u<-v 当 w(Su)>w(Sv)

         u<->v 当 w(Su)=w(Sv)

         那么从一个点沿着边的方向走,直到走到一个区域,使得走不出这个区域,那么这个区域中的任何一个点就是重心.

      2. 有了第一条,就可以运用点分来搞一些询问某个点的的东西了(这里就是询问以这个点为重心的权和).

        再用点分最多log层和类似1的性质,就可以做了.

      3. 点分不擅长求全局最...的东西,而是擅长关于某个点....的东西.

        这道题可以用是因为有重心位置的单调性.

        还有捉迷藏那道题是用堆来辅助的.

      1 #include <cstdio>
      2 #include <vector>
      3 #include <map>
      4 #define max(a,b) ((a)>(b)?(a):(b))
      5 #define oo 0x3f3f3f3f3f3f3f3fLL
      6 #define N 100010
      7 #define M N<<1
      8 #define P 17
      9 using namespace std;
     10 
     11 typedef long long dnt;
     12 struct Info {
     13     int p, s;
     14     Info(){}
     15     Info( int p, int s ):p(p),s(s){}
     16 };
     17 struct Pair {
     18     int s, c;
     19     Pair(){}
     20     Pair( int s, int c ):s(s),c(c){}
     21 };
     22 
     23 int n, m;
     24 int head[N], dest[M], wght[M], next[M], etot;
     25 int idv[M], vid[N], dep[N], stu[M][P+1], stp[M][P+1];
     26 int bac[N], fat[N], siz[N], vis[N], dis[N];
     27 int bin[P+1], log[M], qu[N], bg, ed;
     28 //Info info[N][P+1]; int icnt[N];
     29 //Pair gc[N][22]; int gcnt[N];
     30 vector<Info> info[N];
     31 vector<Pair> gc[N];
     32 dnt cans[N], fans[N], sumw[N];
     33 dnt rans[N]; int tag[N], curt;
     34 
     35 inline void uMax( int &u, int v ) { if( u<v ) u=v; }
     36 void adde( int u, int v, int w ) {
     37     etot++;
     38     dest[etot] = v;
     39     wght[etot] = w;
     40     next[etot] = head[u];
     41     head[u] = etot;
     42 }
     43 void build_lca( int s ) {
     44     //    qu fat dep dis, siz
     45     fat[s] = 0;
     46     dep[s] = 1;
     47     dis[s] = 0;
     48     siz[s] = 0;
     49     qu[bg=ed=1] = s;
     50     while( bg<=ed ) {
     51         int u=qu[bg++];
     52         for( int t=head[u]; t; t=next[t] ) {
     53             int v=dest[t], w=wght[t];
     54             if( v==fat[u] ) continue;
     55             fat[v] = u;
     56             siz[v] = 0;
     57             dep[v] = dep[u]+1;
     58             dis[v] = dis[u]+w;
     59             qu[++ed] = v;
     60         }
     61     }
     62     //    siz
     63     for( register int i=ed; i>=2; i-- ) {
     64         int u=qu[i], p=fat[u];
     65         siz[u]++;
     66         siz[p]+=siz[u];
     67     }
     68     siz[s]++;
     69     //    idv vid
     70     vid[s] = 1;
     71     idv[1] = s;
     72     for( register int i=1; i<=ed; i++ ) {
     73         int u=qu[i];
     74         int cur=vid[u]+1;
     75         for( register int t=head[u]; t; t=next[t] ) {
     76             int v=dest[t];
     77             if( v==fat[u] ) continue;
     78             idv[cur] = u;
     79             cur++;
     80             vid[v] = cur;
     81             idv[cur] = v;
     82             cur += siz[v]+siz[v]-1;
     83         }
     84     }
     85     idv[n+n] = s;
     86     //    bin log
     87     int idc = n+n;
     88     bin[0] = 1;
     89     for( int i=1; i<=P; i++ ) bin[i] = bin[i-1]<<1;
     90     log[0] = -1;
     91     for( int i=1; i<=idc; i++ ) log[i] = log[i>>1]+1;
     92     //    stu stp
     93     for( int i=1; i<=idc; i++ ) {
     94         stu[i][0] = idv[i];
     95         stp[i][0] = dep[idv[i]];
     96     }
     97     for( int p=1; p<=log[idc]; p++ ) {
     98         for( register int i=1; i<=idc-bin[p]+1; i++ ) {
     99             if( stp[i][p-1] < stp[i+bin[p-1]][p-1] ) {
    100                 stp[i][p] = stp[i][p-1];
    101                 stu[i][p] = stu[i][p-1];
    102             } else {
    103                 stp[i][p] = stp[i+bin[p-1]][p-1];
    104                 stu[i][p] = stu[i+bin[p-1]][p-1];
    105             }
    106         }
    107     }
    108 }
    109 inline int lca( int u, int v ) {
    110     int lf=vid[u], rg=vid[v];
    111     if( lf>rg ) swap(lf,rg);
    112     int p = log[rg-lf+1];
    113     if( stp[lf][p] < stp[rg-bin[p]+1][p] )
    114         return stu[lf][p];
    115     else
    116         return stu[rg-bin[p]+1][p];
    117 }
    118 inline int qu_dis( int u, int v ) {
    119     int ca = lca(u,v);
    120     return dis[u]+dis[v]-(dis[ca]<<1);
    121 }
    122 int build_vdcp( int s ) {
    123     int c;
    124     //    qu fat, siz bac
    125     fat[s] = 0;
    126     siz[s] = bac[s] = 0;
    127     qu[bg=ed=1] = s;
    128     while( bg<=ed ) {
    129         int u=qu[bg++];
    130         for( int t=head[u]; t; t=next[t] ) {
    131             int v=dest[t];
    132             if( v==fat[u] || vis[v] ) continue;
    133             fat[v] = u;
    134             siz[v] = bac[v] = 0;
    135             qu[++ed] = v;
    136         }
    137     }
    138     //    siz bac
    139     for( register int i=ed; i>=2; i-- ) {
    140         int u=qu[i], p=fat[u];
    141         siz[u]++;
    142         siz[p]+=siz[u];
    143         uMax( bac[p], siz[u] );
    144     }
    145     siz[s]++;
    146     //    bac c
    147     c = 0;
    148     for( register int i=1; i<=ed; i++ ) {
    149         int u=qu[i];
    150         uMax( bac[u], siz[s]-siz[u] );
    151         if( bac[u]<bac[c] ) c=u;
    152     }
    153     //    qu info
    154     vis[c] = true;
    155     vector<int> stk;
    156     for( int t=head[c]; t; t=next[t] ) {
    157         int s=dest[t], cc;
    158         if( vis[s] ) continue;
    159 
    160         qu[bg=ed=1] = s;
    161         fat[s] = c;
    162         stk.clear();
    163         while( bg<=ed ) {
    164             int u=qu[bg++];
    165             stk.push_back( u );
    166             for( int t=head[u]; t; t=next[t] ) {
    167                 int v=dest[t];
    168                 if( v==fat[u] || vis[v] ) continue;
    169                 qu[++ed] = v;
    170                 fat[v] = u;
    171             }
    172         }
    173         cc = build_vdcp(s);
    174         gc[c].push_back(Pair(s,cc));
    175 //        gc[c][gcnt[c]] = Pair(s,cc);
    176 //        gcnt[c]++;
    177         for( register int t=stk.size()-1; t>=0; t-- )  {
    178             int u=stk[t];
    179             info[u].push_back( Info(c,cc) );
    180 //            info[u][icnt[u]] = Info(c,cc);
    181 //            icnt[u]++;
    182         }
    183     }
    184     return c;
    185 }
    186 dnt query( int u ) {
    187     if( tag[u]==curt ) return rans[u];
    188     tag[u] = curt;
    189     dnt rt = cans[u];
    190     for( int t=0; t<info[u].size(); t++ ) {
    191 //    for( int t=icnt[u]-1; t>=0; t-- ) {
    192         int p=info[u][t].p, s=info[u][t].s;
    193         rt += cans[p]-fans[s]+(sumw[p]-sumw[s])*qu_dis(u,p);
    194     }
    195     return rans[u]=rt;
    196 }
    197 dnt search( int u ) {
    198     dnt su = query(u);
    199     for( int t=0; t<gc[u].size(); t++ ) {
    200 //    for( int t=gcnt[u]-1; t>=0; t-- ) {
    201         Pair &p = gc[u][t];
    202         dnt a=query(p.s);
    203         if( a<su ) return search(p.c);
    204     }
    205     return su;
    206 }
    207 void modify( int u, int delta ) {
    208     sumw[u] += delta;
    209     for( int t=info[u].size()-1; t>=0; t-- ) {
    210 //    for( int t=icnt[u]-1; t>=0; t-- ) {
    211         int p=info[u][t].p, s=info[u][t].s;
    212         dnt d = (dnt)delta*qu_dis(u,p);
    213         cans[p] += d;
    214         fans[s] += d;
    215         sumw[p] += delta;
    216     }
    217 }
    218 int main() {
    219     scanf( "%d%d", &n, &m );
    220     for( int i=1,u,v,w; i<n; i++ ) {
    221         scanf( "%d%d%d", &u, &v, &w );
    222         adde( u, v, w );
    223         adde( v, u, w );
    224     }
    225     bac[0] = n;
    226     int core = build_vdcp(1);
    227     build_lca(1);
    228     for( int t=1,u,d; t<=m; t++ ) {
    229         scanf( "%d%d", &u, &d );
    230         modify( u, d );
    231         curt = t;
    232         printf( "%lld
    ", search(core) );
    233     }
    234 }
    View Code
  • 相关阅读:
    Saltstack module acl 详解
    Saltstack python client
    Saltstack简单使用
    P5488 差分与前缀和 NTT Lucas定理 多项式
    CF613D Kingdom and its Cities 虚树 树形dp 贪心
    7.1 NOI模拟赛 凸包套凸包 floyd 计算几何
    luogu P5633 最小度限制生成树 wqs二分
    7.1 NOI模拟赛 dp floyd
    springboot和springcloud
    springboot集成mybatis
  • 原文地址:https://www.cnblogs.com/idy002/p/4584337.html
Copyright © 2011-2022 走看看