zoukankan      html  css  js  c++  java
  • bzoj3052

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3052

    题目大意:自己看看,懒得写

    题解:带修改的树上莫队,经典爆评测机的题

    代码:

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define maxn 100100
      7 #define ll long long 
      8 using namespace std;
      9 int n,m,q,blo;
     10 ll ans;
     11 int tot,top,totc,totq,lydsytime,belong;
     12 int bin[20],deep[maxn],fa[maxn][20],dfn[maxn];
     13 int z[maxn];
     14 int num[maxn];
     15 int now[maxn],v[maxn*2],pre[maxn*2];
     16 int pos[maxn];
     17 ll res[maxn],val[maxn],c[maxn],cpre[maxn],w[maxn];
     18 bool vis[maxn];
     19 struct data{
     20     int x,y,t,id;
     21     ll pre;
     22 }cg[maxn],bg[maxn];
     23 int read()
     24 {
     25     int x=0; char ch; bool bo=0;
     26     while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1;
     27     while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
     28     if (bo) return -x; return x;
     29 }
     30 bool cmp(data a,data b)
     31 {
     32     if (pos[a.x]==pos[b.x]) return dfn[a.y]<dfn[b.y]; return pos[a.x]<pos[b.x];
     33 }
     34 void ins(int a,int b){++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b;
     35 }
     36 void prework(){ 
     37     bin[0]=1;
     38     for (int i=1; i<=20; i++) bin[i]=bin[i-1]*2;
     39 }
     40 int dfs(int x)
     41 {
     42     int size=0;
     43     dfn[x]=++lydsytime;
     44     for (int i=1; i<=16; i++)
     45         if (deep[x]>=bin[i])
     46             fa[x][i]=fa[fa[x][i-1]][i-1];
     47         else 
     48             break;
     49     for (int p=now[x]; p; p=pre[p])
     50     {
     51         int son=v[p];
     52         if (son==fa[x][0]) continue;
     53         deep[son]=deep[x]+1;
     54         fa[son][0]=x;
     55         size+=dfs(son);
     56         if (size>blo)
     57         {
     58             belong++;
     59             for (int i=1; i<=blo; i++) pos[z[top--]]=belong;
     60             size=0;
     61         }
     62     }
     63     z[++top]=x;
     64     return size+1;
     65 }
     66 int lca(int x,int y)
     67 {
     68 //    cout<<" pre "<<x<<" "<<y<<endl;
     69     if (deep[x]<deep[y]) swap(x,y);
     70     int t=deep[x]-deep[y];
     71     for (int i=0; bin[i]<=t; i++)
     72         if (bin[i]&t)
     73         x=fa[x][i];
     74     for (int i=17; i>=0; i--)
     75         if (fa[x][i]!=fa[y][i])
     76             x=fa[x][i], y=fa[y][i];
     77 //    cout<<" now "<<x<<" "<<y<<endl;
     78     if (x==y) return x;
     79     return fa[x][0];
     80 }
     81 void reverse(int x)
     82 {
     83     //cout<<"                                         re "<<x<<" "<<c[x]<<" "<<val[c[x]]<<" "<<num[c[x]]<<" "<<w[num[c[x]]+1]<<" "<<w[1]<<endl;
     84     if (vis[x]) ans-=val[c[x]]*w[num[c[x]]],num[c[x]]--;
     85     else num[c[x]]++,ans+=val[c[x]]*w[num[c[x]]];
     86     vis[x]^=1;
     87 }
     88 void work(int u,int v)
     89 {
     90     //cout<<"             pre u v     "<<u<<" "<<v<<endl;
     91     while (u!=v)
     92     {
     93         if (deep[u]>deep[v])
     94         {
     95             reverse(u);
     96             u=fa[u][0];
     97         }
     98         else
     99         {
    100             reverse(v);
    101             v=fa[v][0];
    102         }
    103         //cout<<" now u v "<<u<<" "<<v<<" "<<endl;
    104     }
    105 }
    106 void change(int x,int y)
    107 {
    108     if (vis[x])
    109     {
    110         reverse(x);
    111         c[x]=y;
    112         reverse(x);
    113     }
    114     else c[x]=y;
    115 }
    116 void init()
    117 {
    118     n=read(); m=read(); q=read();
    119     blo=pow(n,2.0/3)*0.5;
    120     for (int i=1; i<=m; i++) val[i]=read();
    121     for (int i=1; i<=n; i++) w[i]=read();
    122     for (int i=1; i<n; i++)
    123     {
    124         int u=read(),v=read();
    125         ins(u,v); ins(v,u);
    126     }
    127     dfs(1);
    128     //for (int i=1; i<=n; i++) cout<<"           dsdsd   "<<fa[i][0]<<" "<<dfn[i]<<endl;
    129     belong++;
    130     while (top) pos[z[top--]]=belong;
    131     for (int i=1; i<=n; i++) c[i]=cpre[i]=read();
    132     for (int i=1; i<=q; i++)
    133     {
    134         int type=read(),x=read(),y=read();
    135         if (!type)
    136         {
    137             totc++; cg[totc].x=x,cg[totc].y=y,cg[totc].pre=cpre[x],cpre[x]=y;
    138         }
    139         else
    140         {
    141             totq++; bg[totq].x=x,bg[totq].y=y,bg[totq].t=totc; bg[totq].id=totq;
    142         }    
    143     }
    144     sort(bg+1,bg+totq+1,cmp);
    145     /*for (int i=1; i<=totq; i++)
    146     {
    147         cout<<" "<<bg[i].x<<" "<<bg[i].y<<" "<<bg[i].t<<" "<<endl;
    148     }*/
    149 }
    150 void solve()
    151 {
    152     for (int i=1; i<=bg[1].t; i++) change(cg[i].x,cg[i].y);
    153     work(bg[1].x,bg[1].y); 
    154     int t=lca(bg[1].x,bg[1].y); 
    155     //cout<<" "<<t<<" "<<bg[1].x<<" "<<bg[1].y<<endl;
    156     reverse(t); res[bg[1].id]=ans; reverse(t);
    157     for (int i=2; i<=totq; i++)
    158     {
    159         for (int j=bg[i-1].t+1; j<=bg[i].t; j++)
    160             change(cg[j].x,cg[j].y);
    161         for (int j=bg[i-1].t+1; j>bg[i].t; j--)
    162             change(cg[j].x,cg[j].pre);
    163         work(bg[i-1].x,bg[i].x); work(bg[i-1].y,bg[i].y);
    164         int t=lca(bg[i].x,bg[i].y);
    165         reverse(t); res[bg[i].id]=ans; reverse(t);
    166     }
    167 }
    168 int main()
    169 {
    170     prework();
    171     init();
    172     solve();
    173     for (int i=1; i<=totq; i++)
    174         printf("%lld
    ",res[i]);
    175 }
    176 /*
    177 4 3 5
    178 1 9 2
    179 7 6 5 1
    180 2 3
    181 3 1
    182 3 4
    183 1 2 3 2
    184 1 1 2
    185 1 4 2
    186 0 2 1
    187 1 1 2
    188 1 4 2
    189 */
    View Code

    一次CE,一次WA,一次AC

    -------------哦,对了这道题还是有个坑,就是怎么推出带修改的树上莫队时间复杂度!待zfy来教我补!

  • 相关阅读:
    从头到尾测地理解KMP算法【转】
    【Android】使用BaseAdapter实现复杂的ListView【转】
    Git命令速查表【转】
    图解Git命令【转】
    Git-入门教程
    自定义Git【转】
    linux命令大全
    ppt转pdf网址
    【转】设置电脑眼睛保护色(背景色)
    【转】putty基本操作--不错
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5574699.html
Copyright © 2011-2022 走看看