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
  • 相关阅读:
    iOS 数据存储
    iOS 中@property() 括号中,可以填写的属性?
    iOS 中关闭键盘方法
    iBeacons 资源汇总
    iOS7 下去掉状态栏(全屏)
    监听器HttpSessionListener
    监听器 HttpSessionBindingListener
    servlet 3.0 的使用
    工厂模式小例子 getDaoImp
    servlet和filter初始化
  • 原文地址:https://www.cnblogs.com/idy002/p/4584337.html
Copyright © 2011-2022 走看看