思路:

就是把带修莫队移到了树上

块的大小开到(n^2/3)/2 比较好…

这是一个卡OJ好题

//By SiriusRen
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100050;
int n,m,q,xx,yy,Block,block[N],cnt=1,fa[N][20],tot,top,cnt1,cnt2,op,num[N];
int first[N],next[N*2],v[N*2],C[N],stk[N],deep[N],V[N],W[N],last[N],vis[N];
typedef long long ll;ll Ans[N],ans;
struct Query{
int l,r,lca,id,time;Query(){}
Query(int ll,int rr,int zz,int ii,int tt){l=ll,r=rr,lca=zz,id=ii,time=tt;}
friend bool operator<(Query a,Query b){
if(block[a.l]==block[b.l]){
if(block[a.r]==block[b.r])return a.time<b.time;
return block[a.r]<block[b.r];
}
return block[a.l]<block[b.l];
}
}query[N];
struct Change{
int position,color,lastcolor;Change(){}
Change(int pp,int cc,int ll){position=pp,color=cc,lastcolor=ll;}
}change[N];
void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void dfs(int x){
for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x][0])
fa[v[i]][0]=x,deep[v[i]]=deep[x]+1,dfs(v[i]);
stk[++top]=x;
if(top==Block){
for(int i=1;i<=top;i++)block[stk[i]]=cnt;
top=0,cnt++;
}
}
int lca(int x,int y){
if(deep[x]<deep[y])swap(x,y);
for(int i=19;i>=0;i--)if(deep[x]-(1<<i)>=deep[y])x=fa[x][i];
if(x==y)return x;
for(int i=19;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
void reverse(int x){
if(vis[x])ans-=(ll)V[C[x]]*W[num[C[x]]],num[C[x]]--;
else num[C[x]]++,ans+=(ll)V[C[x]]*W[num[C[x]]];
vis[x]^=1;
}
void change_color(int x,int y){
if(vis[x])reverse(x),C[x]=y,reverse(x);
else C[x]=y;
}
void work(int x,int y){
while(x!=y){
if(deep[x]<deep[y])swap(x,y);
reverse(x),x=fa[x][0];
}
}
int read(){
char p=getchar();int x=0;
while(p<'0'||p>'9')p=getchar();
while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();
return x;
}
int main(){
memset(first,-1,sizeof(first));
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=m;i++)V[i]=read();
for(int i=1;i<=n;i++)W[i]=read();
Block=pow(n,2.0/3.0)*0.5;
for(int i=1;i<n;i++)xx=read(),yy=read(),add(xx,yy),add(yy,xx);
deep[1]=1,dfs(1);
for(int i=1;i<=top;i++)block[stk[i]]=cnt;
for(int j=1;j<=19;j++)
for(int i=1;i<=n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
for(int i=1;i<=n;i++)C[i]=read(),last[i]=C[i];
for(int i=1;i<=q;i++){
op=read(),xx=read(),yy=read();
if(op){
if(block[xx]>block[yy])swap(xx,yy);
query[++cnt1]=Query(xx,yy,lca(xx,yy),cnt1,cnt2);
}
else change[++cnt2]=Change(xx,yy,last[xx]),last[xx]=yy;
}
sort(query+1,query+1+cnt1);
for(int i=1,T=0;i<=cnt1;i++){
for(;T<query[i].time;T++)change_color(change[T+1].position,change[T+1].color);
for(;T>query[i].time;T--)change_color(change[T].position,change[T].lastcolor);
if(i==1)work(query[i].l,query[i].r);
else work(query[i-1].l,query[i].l),work(query[i-1].r,query[i].r);
reverse(query[i].lca),Ans[query[i].id]=ans,reverse(query[i].lca);
}
for(int i=1;i<=cnt1;i++)printf("%lld\n",Ans[i]);
}

BZOJ 3052 树上带修莫队的更多相关文章

  1. BZOJ 4129 树上带修莫队+线段树

    思路: 可以先做做BZOJ3585 是序列上的mex 考虑莫队的转移 如果当前数字出现过 线段树上把它置成1 对于询问 二分ans 线段树上查 0到ans的和 是不是ans+1 本题就是把它搞到了序列 ...

  2. BZOJ 3052/Luogu P4074 [wc2013]糖果公园 (树上带修莫队)

    题面 中文题面,难得解释了 BZOJ传送门 Luogu传送门 分析 树上带修莫队板子题... 开始没给分块大小赋初值T了好一会... CODE #include <bits/stdc++.h&g ...

  3. BZOJ 4129 Haruna’s Breakfast ( 树上带修莫队 )

    题面 求树上某路径上最小的没出现过的权值,有单点修改 添加链接描述 分析 树上带修莫队板题,问题是怎么求最小的没出现过的权值. 因为只有nnn个点,所以没出现过的最小值一定在[0,n][0,n][0, ...

  4. 【BZOJ-3052】糖果公园 树上带修莫队算法

    3052: [wc2013]糖果公园 Time Limit: 200 Sec  Memory Limit: 512 MBSubmit: 883  Solved: 419[Submit][Status] ...

  5. LUOGU P4074 [WC2013]糖果公园 (树上带修莫队)

    传送门 解题思路 树上带修莫队,搞了两天..终于开O2+卡常大法贴边过了...bzoj上跑了183s..其实就是把树上莫队和带修莫队结合到一起,首先求出括号序,就是进一次出一次那种的,然后如果求两个点 ...

  6. BZOJ3052: [wc2013]糖果公园【树上带修莫队】

    Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT 思路 非常模板的树上带修莫队 真的 ...

  7. luogu4074 [WC2013]糖果公园(树上带修莫队)

    link 题目大意:给一个树,树上每个点都有一种颜色,每个颜色都有一个收益 每次修改一个点上的颜色 或询问一条链上所有颜色第i次遇到颜色j可以获得w[i]*v[j]的价值,求链上价值和 题解:树上带修 ...

  8. bzoj4129 Haruna’s Breakfast 树上带修莫队+分块

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4129 题解 考虑没有修改的序列上的版本应该怎么做: 弱化的题目应该是这样的: 给定一个序列,每 ...

  9. BZOJ3052(树上带修莫队)

    树上莫队的基本思路是把树按dfs序分块,然后先按x所在块从小到大排序,再按y所在块从小到大排序,处理询问即可. 这道题带修改,再加一个时间维即可. 设块大小为T,那么时间复杂度为$O(nT+\frac ...

随机推荐

  1. 微信小程序video组件出现无法播放或卡顿

    微信小程序使用video组件播放视频的时候,会出现卡顿或者无法播放的问题,加一个custom-cache=”true“即可解决,这个属性文档上没有,是从小程序开发社区中get到的.

  2. Java I/O streams

    I/O Streams Byte Streams 输入输出以字节为单位,所有的使用字节流的类都继承自 InputStream 和 OutputStream. Byte Streams 属于 low-l ...

  3. 1350 Taxi Cab Scheme DAG最小路径覆盖

    对于什么是DAG最小路径覆盖以及解题方法在我的另外的博客已经有了.http://www.cnblogs.com/Potato-lover/p/3980470.html 此题的题意: 公交车(出租车)车 ...

  4. 【Linux】SecureCRT中按退格键出现^H

    分两步: ①SecureCRT上部的“选项”→“会话选项”→终端→仿真→映射键→其他映射→Backspace发送delete(B) 勾选中,确定 ②SecureCRT上部的“选项”→全局选项→常规→默 ...

  5. 谷歌C++编程为何禁止缺省参数

    C++的缺省参数尽量不要使用,结果可能出乎我们的意料,下面的程序大家看看输出结果是多少? )                  cout << num << endl;     ...

  6. 根据业务自己设计的.NET工厂模式架构

    最近项目的架构需要做调整优化,根据业务需要写了一个简单的工厂模式架构 项目介绍:整个系统分为三大平台(这里用A,B,C来标示),每个平台又细分为多个APP客户端(每个APP都有appid来区分) 因为 ...

  7. 设计模式(C++实现)--一句话总结

    原文链接:http://blog.csdn.net/LCL_data/article/details/12117349 按照目的来分,设计模式可以分为创建型模式.结构型模式和行为型模式. 按照目的来分 ...

  8. 几个书本上不常见到的C语言函数

    函数名称:getcwd #include <unistd.h> char *getcwd(char *buf, size_t size); 作用:把当前目录的绝对地址保存到 buf 中,b ...

  9. 在Linux Centos 7.2 上安装指定版本Docker 17.03

    相关资料链接: https://docs.docker.com/install/linux/docker-ce/centos/#install-docker-ce 先清空下“历史” yum insta ...

  10. Win7系统无法记住网络访问的凭据怎么办?

    访问内网其他IP时已经打勾记住我的凭据了,但是注销或者重启Win7系统之后,又得重新输入用户名跟密码怎么办? 下面就为大家介绍一下如何让Win7系统记住网络访问的凭据. 以上问题还会引发,重启后无法正 ...