• [WC2013][luogu4074] 糖果公园 [树上带修改莫队]


    题面:

    传送门

    思路:

    一道实现起来细节比较恶心的题目

    但是其实就是一个裸的树上带修改莫队

    好像树上莫队也出不了什么结合题目,不像序列莫队天天结合AC自动机、后缀数组......

    莫队学习请戳这里:莫队

    Code:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define ll long long
      7 using namespace std;
      8 inline ll read(){
      9     ll re=0,flag=1;char ch=getchar();
     10     while(ch>'9'||ch<'0'){
     11         if(ch=='-') flag=-1;
     12         ch=getchar();
     13     }
     14     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
     15     return re*flag;
     16 }
     17 struct edge{
     18     ll to,next;
     19 }a[200010];
     20 ll n,m,Q,first[100010],cntt,clk,block;
     21 ll fa[100010],dep[100010],st[100010][20],dfn[100010];
     22 ll v[100010],w[100010],x[100010];
     23 inline void add(ll u,ll v){
     24     a[++cntt]=(edge){v,first[u]};first[u]=cntt;
     25     a[++cntt]=(edge){u,first[v]};first[v]=cntt;
     26 }
     27 void dfs(ll u,ll f){
     28     //cout<<"dfs "<<u<<" "<<f<<"
    ";
     29     ll i,v;
     30     fa[u]=st[u][0]=f;dep[u]=dep[f]+1;dfn[u]=++clk;
     31     for(i=first[u];~i;i=a[i].next){
     32         v=a[i].to;
     33         if(v==f) continue;
     34         dfs(v,u);
     35     }
     36 }
     37 void init(){
     38     for(ll i=1;i<=18;i++){
     39         for(ll j=1;j<=n;j++){
     40             st[j][i]=st[st[j][i-1]][i-1];
     41         }
     42     }
     43 }
     44 void _swap(ll &l,ll &r){l^=r;r^=l;l^=r;}
     45 ll LCA(ll l,ll r){
     46     //cout<<"lca "<<l<<" "<<r<<"
    ";
     47     if(dep[l]>dep[r]) _swap(l,r);
     48     ll i;
     49     for(i=18;i>=0;i--) if(dep[st[r][i]]>=dep[l]) r=st[r][i];
     50     if(l==r) return l;
     51     for(i=18;i>=0;i--){
     52         if(st[l][i]!=st[r][i]){
     53             l=st[l][i];r=st[r][i];
     54         }
     55     }
     56     return fa[l];
     57 }
     58 ll curl,curr,curc,cntq,cntc,cnt[1000010];bool vis[100010];
     59 ll ans[100010],tot;
     60 struct query{
     61     ll l,r,c,i;
     62 }q[100010];
     63 bool cmp(query l,query r){
     64     if(dfn[l.l]/block!=dfn[r.l]/block) return dfn[l.l]/block<dfn[r.l]/block;
     65     else{
     66         if(dfn[l.r]/block!=dfn[r.r]/block) 
     67             return dfn[l.r]/block<dfn[r.r]/block;
     68         else return l.c<r.c;
     69     }
     70 }
     71 struct change{
     72     ll pos,to;
     73 }c[100010];
     74 void rev(ll i){
     75     if(vis[i]) vis[i]=0,tot-=v[x[i]]*w[cnt[x[i]]],cnt[x[i]]--;
     76     else vis[i]=1,cnt[x[i]]++,tot+=v[x[i]]*w[cnt[x[i]]];
     77     //cout<<"rev node "<<i<<" "<<x[i]<<" "<<tot<<"
    ";
     78 }
     79 void change(ll i){
     80     //cout<<"change node "<<i<<" "<<c[i].pos<<" "<<c[i].to<<"
    ";
     81     if(!vis[c[i].pos]) _swap(c[i].to,x[c[i].pos]);
     82     else{
     83         rev(c[i].pos);
     84         _swap(c[i].to,x[c[i].pos]);
     85         rev(c[i].pos);
     86     }
     87 }
     88 int main(){
     89     memset(first,-1,sizeof(first));
     90     ll i,t1,t2,t3;
     91     n=read();m=read();Q=read();block=(ll)pow(n,0.60);
     92     for(i=1;i<=m;i++) v[i]=read(); 
     93     for(i=1;i<=n;i++) w[i]=read();
     94     for(i=1;i<n;i++){
     95         t1=read();t2=read();add(t1,t2);
     96     }
     97     for(i=1;i<=n;i++) x[i]=read();
     98     dfs(1,0);init();
     99     //for(i=1;i<=n;i++) cout<<fa[i]<<" "<<dep[i]<<"
    ";
    100     for(i=1;i<=Q;i++){
    101         t1=read();t2=read();t3=read();
    102         if(t1) q[++cntq].l=t2,q[cntq].r=t3,q[cntq].c=cntc,q[cntq].i=cntq;
    103         else c[++cntc].pos=t2,c[cntc].to=t3;
    104         //cout<<"finish read in "<<i<<"
    ";
    105     }
    106     sort(q+1,q+cntq+1,cmp);
    107     //for(i=1;i<=cntq;i++) 
    108         //cout<<q[i].l<<" "<<q[i].r<<" "<<q[i].c<<" "<<q[i].i<<"
    ";
    109     
    110     if(dfn[q[1].l]>dfn[q[1].r]) _swap(q[1].l,q[1].r);
    111     ll lca=LCA(q[1].l,q[1].r),l,r;curl=q[1].l;curr=q[1].r;
    112     l=curl;r=curr;
    113     while(l!=lca) rev(l),l=fa[l];
    114     while(r!=lca) rev(r),r=fa[r];
    115     while(curc<q[1].c) change(++curc);
    116     rev(lca);ans[q[1].i]=tot;rev(lca);
    117     for(i=2;i<=cntq;i++){
    118         //cout<<"i=="<<i<<"
    ";
    119         if(dfn[q[i].l]>dfn[q[i].r]) _swap(q[i].l,q[i].r);
    120         lca=LCA(curr,q[i].r);l=curr;r=q[i].r;
    121         while(l!=lca) rev(l),l=fa[l];
    122         while(r!=lca) rev(r),r=fa[r];
    123         lca=LCA(curl,q[i].l);l=curl;r=q[i].l;
    124         while(l!=lca) rev(l),l=fa[l];
    125         while(r!=lca) rev(r),r=fa[r];
    126         while(curc>q[i].c) change(curc--);
    127         while(curc<q[i].c) change(++curc);
    128         lca=LCA(q[i].l,q[i].r);
    129         rev(lca);ans[q[i].i]=tot;rev(lca);
    130         curl=q[i].l;curr=q[i].r;
    131     }
    132     for(i=1;i<=cntq;i++) printf("%lld
    ",ans[i]);
    133 }
  • 相关阅读:
    [sql]在case语句中不同情况下then的数据的数据类型不一致ORA-00932: inconsistent datatypes: expected NUMBER got CHAR
    环境迁移 小记
    linux下安装oracle遇到的问题
    正向代理与反向代理
    文件夹与SVN脱离关系
    shell 脚本中$$,$#,$?
    在MySQL中单列索引和联合索引的区别
    Java中Map、HashMap、LinkedHashMap、TreeMap的区别
    Error、Exception与RuntimeException的区别
    设计模式--单例模式
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8503874.html
Copyright © 2020-2023  润新知