码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 3052 树上莫队 待修改

时间:2015-02-25 00:44:55      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:

 

感谢:

http://vfleaking.blog.163.com/blog/static/174807634201311011201627/

http://hzwer.com/5250.html

 

好吧,收获两点:

  1、带修改,其实就是暴力,只是将同一块的查询再按照时间顺序排,这样就能减少在修改操作上“爬"的时间,其实就是利用了数据随机这个特点,可以构造数据来卡。

  2、以前排序的方法是u按照块,v按照dfs序,这次两个都是按照块,其实差不多。

 

技术分享
  1 /**************************************************************
  2     Problem: 3052
  3     User: idy002
  4     Language: C++
  5     Result: Accepted
  6     Time:101223 ms
  7     Memory:21792 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cmath>
 12 #include <vector>
 13 #include <algorithm>
 14 #define P(p) ((1)<<(p))
 15 #define maxn 100010
 16 #define maxp 16
 17 using namespace std;
 18  
 19 typedef long long dint;
 20  
 21 int n, m, q, qq, qm;
 22 int cc[maxn], ww[maxn], vv[maxn];
 23 vector<int> g[maxn], stk;
 24 int mno[maxn], mcc_siz, mcc_cnt;
 25 int anc[maxn][maxp+1], depth[maxn], dfn[maxn], dfs_clock;
 26 bool stat[maxn];
 27 dint cnt[maxn], cur_ans;
 28 dint ans[maxn];
 29 int mdu[maxn], mdc[maxn], mdo[maxn], mdcc[maxn];
 30  
 31 struct Qu {
 32     int u, v, t, id;
 33     bool operator<( const Qu & b ) const {
 34         if( mno[u]^mno[b.u] ) return mno[u]<mno[b.u];
 35         if( mno[v]^mno[b.v] ) return mno[v]<mno[b.v];
 36         return t<b.t;
 37     }
 38 };
 39 Qu qu[maxn];
 40  
 41 int dfs( int u ) {
 42     dfn[u] = ++dfs_clock;
 43     depth[u] = depth[anc[u][0]]+1;
 44     for( int p=1; p<=maxp; p++ ) {
 45         anc[u][p] = anc[anc[u][p-1]][p-1];
 46         if( !anc[u][p] ) break;
 47     }
 48  
 49     int sz = 0;
 50     for( int t=0; t<g[u].size(); t++ ) {
 51         int v = g[u][t];
 52         if( v==anc[u][0] ) continue;
 53         anc[v][0] = u;
 54         sz += dfs(v);
 55         if( sz > mcc_siz ) {
 56             mcc_cnt++;
 57             for( int i=1; i<=sz; i++ ) {
 58                 mno[stk.back()] = mcc_cnt;
 59                 stk.pop_back();
 60             }
 61             sz = 0;
 62         }
 63     }
 64     stk.push_back( u );
 65     return sz+1;
 66 }
 67  
 68 int lca( int u, int v ) {
 69     if( depth[u]<depth[v] ) swap(u,v);
 70     int t = depth[u]-depth[v];
 71     for( int p=0; t; t>>=1, p++ ) 
 72         if( t&1 ) u=anc[u][p];
 73     if( u==v ) return u;
 74     for( int p=maxp; p>=0 && anc[u][0]!=anc[v][0]; p-- ) 
 75         if( anc[u][p]!=anc[v][p] ) 
 76             u = anc[u][p], v = anc[v][p];
 77     return anc[u][0];
 78 }
 79  
 80 void inv_sig( int u ) {
 81     if( stat[u] ) {
 82         cur_ans -= (dint)ww[cnt[cc[u]]]*vv[cc[u]];
 83         cnt[cc[u]]--;
 84     } else {
 85         cnt[cc[u]]++;
 86         cur_ans += (dint)ww[cnt[cc[u]]]*vv[cc[u]];
 87     }
 88     stat[u] ^= 1;
 89 }
 90  
 91 void chg_sig( int u, int type ) {
 92     if( stat[u] ) {
 93         inv_sig(u);
 94         cc[u] = type;
 95         inv_sig(u);
 96     } else cc[u] = type;
 97 }
 98  
 99 void inv_chain( int u, int v ) {
100     int ca = lca(u,v);
101     for( ; u!=ca; u=anc[u][0] ) inv_sig(u);
102     for( ; v!=ca; v=anc[v][0] ) inv_sig(v);
103 }
104 void app_time( int fm, int to ) {
105     while( fm<to ) {
106         fm++;
107         chg_sig(mdu[fm],mdc[fm]);
108     }
109     while( to<fm ) {
110         chg_sig(mdu[fm],mdo[fm]);
111         fm--;
112     }
113 }
114  
115 void work() {
116     sort( qu+1, qu+1+qq );
117     int ou=qu[1].u;
118     int ov=qu[1].u;
119     int ot=0;
120     for( int i=1; i<=qq; i++ ) {
121         int u = qu[i].u, v = qu[i].v;
122         inv_chain( u, ou );
123         inv_chain( v, ov );
124         app_time( ot, qu[i].t );
125         ot = qu[i].t;
126         ou = u;
127         ov = v;
128         int ca = lca(u,v);
129         inv_sig( ca );
130         ans[qu[i].id] = cur_ans;
131         inv_sig( ca );
132     }
133 }
134  
135 int main() {
136     scanf( "%d%d%d", &n, &m, &q );
137     for( int i=1; i<=m; i++ ) scanf( "%d", vv+i );
138     for( int i=1; i<=n; i++ ) scanf( "%d", ww+i );
139     for( int i=1,u,v; i<n; i++ ) {
140         scanf( "%d%d", &u, &v );
141         g[u].push_back(v);
142         g[v].push_back(u);
143     }
144     mcc_siz = (int)(pow(n,2.0/3.0))+1;
145     dfs(1);
146     while( !stk.empty() ) {
147         mno[stk.back()] = mcc_cnt;
148         stk.pop_back();
149     }
150     for( int i=1; i<=n; i++ ) {
151         scanf( "%d", cc+i );
152         mdcc[i] = cc[i];
153     }
154     for( int i=1,type,x,y; i<=q; i++ ) {
155         scanf( "%d%d%d", &type, &x, &y );
156         if( !type ) {
157             qm++;
158             mdu[qm]=x, mdc[qm]=y, mdo[qm]=mdcc[x];
159             mdcc[x] = y;
160         } else {
161             qq++;
162             qu[qq].u=x, qu[qq].v=y, qu[qq].t=qm, qu[qq].id=qq;
163         }
164     }
165     work();
166     for( int i=1; i<=qq; i++ ) 
167         printf( "%lld\n", ans[i] );
168 }
View Code

 

bzoj 3052 树上莫队 待修改

标签:

原文地址:http://www.cnblogs.com/idy002/p/4299078.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!