【BZOJ】【3052】【WC2013】糖果公园
树分块
老早(大约一个月以前?)就听说这道神题了……orz rausen
一直拖到现在才做……发现还是不会呢= = 只好也去Orz了Hzwer和zky
http://hzwer.com/5250.html http://blog.csdn.net/iamzky/article/details/42125999这个树上莫队真的蛮神奇的……
1.对于每个查询,记录它是在第几次修改之后的;
2.以左端点所在块为第一关键字、右端点所在块为第二关键字、时间(第几次修改之后的查询)为第三关键字进行排序;
3.对于每个查询,先进行时间上的移动(这个只需对变化了的点进行单点修改即可,有点小Z的袜子中 +1-1的感觉)再进行查询序列的移动(用之前讲的vfk的方法……)至于第二步就跟普通的树分块一样了么……
注意:由于时间移动既有向前也有向后的,所以除了要记录是把哪个点变成了什么糖果,还要记录变化前的原来的状态(时光回溯时用)(用“时光回溯”这个名字是不是十分高大上~~)
错误:1.所有数据点的答案范围都是long long!!
2.读入单点修改糖果种类的时候,pre[x]=y; 写成了 pre[c2]=y; QAQ唉细节啊细节!!!pre数组是对点进行“时光回溯”保存的,不是对修改序号进行保存!!!理解不到位啊……(白问大视野要数据了……)
/**************************************************************
Problem: 3052
User: Tunix
Language: C++
Result: Accepted
Time:117744 ms
Memory:25256 kb
****************************************************************/ //BZOJ 3052
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std; int getint(){
int v=,sign=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') sign=-; ch=getchar();}
while(isdigit(ch)) {v=v*+ch-''; ch=getchar();}
return v*=sign;
}
typedef long long LL;
/******************tamplate*********************/
const int N=;
LL w[N],v[N];
int n,m,Q;
int head[N],next[N<<],to[N<<],cnt;
void add(int x,int y){
to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt;
to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt;
}
/*******************edge************************/
int B;
int st[N],top,deep[N],belong[N],tot;
int fa[N][],bin[];
void dfs(int x){
int bottom=top;
F(i,,)
if(deep[x]>=bin[i])
fa[x][i]=fa[fa[x][i-]][i-];
else break;
for(int i=head[x];i;i=next[i])
if (to[i]!=fa[x][]){
fa[to[i]][]=x;
deep[to[i]]=deep[x]+;
dfs(to[i]);
if(top-bottom>=B){
++tot;
while(top!=bottom)
belong[st[top--]]=tot;
}
}
st[++top]=x;
}
int LCA(int x,int y){
if(deep[x]<deep[y]) swap(x,y);
int t=deep[x]-deep[y];
for(int i=;bin[i]<=t;i++)
if(t&bin[i]) x=fa[x][i];
D(i,,)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
if(x==y) return x;
return fa[x][];
}
/*********************dfs&&LCA******************/
struct ques{
int x,y,ti,num;
bool operator < (const ques&now)const{
if(belong[x]==belong[now.x]){
if(belong[y]==belong[now.y]) return ti<now.ti;
else return belong[y]<belong[now.y];
}
else return belong[x]<belong[now.x];
}
}q[N];
struct Time{
int x,y,pre;
}change[N];
int pre[N]; LL ans=,answer[N];
int c[N],num[N],now;
bool used[N];
/*****************分块变量声明******************/
void work(int x){
if (used[x]){
ans-=v[c[x]]*w[num[c[x]]]; num[c[x]]--; used[x]=;
}
else{
num[c[x]]++; ans+=v[c[x]]*w[num[c[x]]]; used[x]=;
}
}
void Xor(int x,int y){
while(x!=y)
if(deep[x]>deep[y]) {work(x);x=fa[x][];}
else {work(y); y=fa[y][];}
}
void Change(int x,int y){//将点x的糖果改为第y种 (权值改为y)
if(used[x]){work(x); c[x]=y; work(x);}
else c[x]=y;
}
void TimeMachine(int tarti){
for(int i=now+;i<=tarti;i++) Change(change[i].x,change[i].y);
for(int i=now;i>tarti;i--) Change(change[i].x,change[i].pre);
now=tarti;
}
/*****************分块函数声明******************/
int main(){
bin[]=; F(i,,) bin[i]=bin[i-]<<; n=getint(); m=getint(); Q=getint();
B=pow(n,2.0/3.0);
int x,y;
F(i,,m) v[i]=getint();//美味指数
F(i,,n) w[i]=getint();//新奇指数
F(i,,n){
x=getint(); y=getint();
add(x,y);
} dfs();
tot++;
while(top) belong[st[top--]]=tot;
F(i,,n) pre[i]=c[i]=getint();//每个节点的糖果种类 int cmd,c1=,c2=;
F(i,,Q){
cmd=getint(); x=getint(); y=getint();
if (cmd){
c2++;
if(belong[x]>belong[y]) swap(x,y);
q[c2]=(ques){x,y,c1,c2};//记录是第几次修改之后的查询
}
else{
c1++;
change[c1]=(Time){x,y,pre[x]};
pre[x]=y;
//有点前向星的感觉,pre[i]保存第i个节点当前是什么种类的糖果
}
}
sort(q+,q+c2+);
//读入&&初始化 end int lca=LCA(q[].x,q[].y);
TimeMachine(q[].ti);
Xor(q[].x,q[].y);
work(lca);
answer[q[].num]=ans;
work(lca);
F(i,,c2){
TimeMachine(q[i].ti);
Xor(q[i-].x,q[i].x);
Xor(q[i-].y,q[i].y);
lca=LCA(q[i].x,q[i].y);
work(lca);
answer[q[i].num]=ans;
work(lca);
}
F(i,,c2) printf("%lld\n",answer[i]);
return ;
}
【BZOJ】【3052】【WC2013】糖果公园的更多相关文章
- bzoj 3052: [wc2013]糖果公园 带修改莫队
3052: [wc2013]糖果公园 Time Limit: 250 Sec Memory Limit: 512 MBSubmit: 506 Solved: 189[Submit][Status] ...
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- BZOJ 3052: [wc2013]糖果公园 | 树上莫队
题目: UOJ也能评测 题解 请看代码 #include<cstdio> #include<algorithm> #include<cstring> #includ ...
- bzoj 3052: [wc2013]糖果公园【树上带修改莫队】
参考:http://blog.csdn.net/lych_cys/article/details/50845832 把树变成dfs括号序的形式,注意这个是不包含lca的(除非lca是两点中的一个) 然 ...
- 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法
[题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...
- 【BZOJ】3052: [wc2013]糖果公园
http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...
- 洛谷 P4074 [WC2013]糖果公园 解题报告
P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...
- AC日记——[WC2013]糖果公园 cogs 1817
[WC2013]糖果公园 思路: 带修改树上莫队(模板): 来,上代码: #include <cmath> #include <cstdio> #include <cst ...
- COGS1817. [WC2013]糖果公园
1817. [WC2013]糖果公园 ★★★☆ 输入文件:park.in 输出文件:park.out 简单对比时间限制:8 s 内存限制:512 MB [题目描述] Candyland ...
随机推荐
- ubuntu安装python3
系统本身就已经安装了python2.7 和python3.4 现在需要做的就是将默认的版本更换一下下就可以了. 检查python的版本 python -V 老的版本没必要去产出了,因为会有一些程序依赖 ...
- 《iOS开发指南》正式出版-源码-样章-目录,欢迎大家提出宝贵意见
智捷iOS课堂-关东升老师最新作品:<iOS开发指南-从0基础到AppStore上线>正式出版了 iOS架构设计.iOS性能优化.iOS测试驱动.iOS调试.iOS团队协作版本控制.... ...
- Objective-C 【电商APP应用代码-系统分析-详细注释-代码实现】
------------------------------------------- 电商APP应用 ************************************************ ...
- 转载:简单介绍Python中的try和finally和with方法
用 Python 做一件很平常的事情: 打开文件, 逐行读入, 最后关掉文件; 进一步的需求是, 这也许是程序中一个可选的功能, 如果有任何问题, 比如文件无法打开, 或是读取出错, 那么在函数内需要 ...
- IoC容器的初始化过程
1.简单来说,IoC容器的初始化是由前面介绍的refresh()方法来启动的,这个方法标志着IoC容器的正式启动. 2.具体来说,这个启动包括BeanDefinition的Resource定位.载入和 ...
- QQ截图工具提取
今晚关了QQ,突然想截个图,但是呢又不想打开QQ了,于是在网上搜索截图工具,下载了几个,感觉都没有QQ截图好用.索性直接百度QQ截图工具提取,看到有些网站上有提取的,里面的文件有点多,不是我中意的,突 ...
- Windows 命令大全
打开控制面板的方法:输入control,回车即可打开. 以下是“运行”里常见的命令: gpedit.msc-----组策略 sndrec32-------录音机 Nslookup-------IP地址 ...
- C++ 单链表基本操作
链表一直是面试的高频题,今天先总结一下单链表的使用,下节再总结双向链表的.本文主要有单链表的创建.插入.删除节点等. 1.概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数 ...
- Viewport Resizer下载 谷歌前端自适应开发工具
原文链接:http://www.phpbiji.cn/article/index/id/107/cid/6.html Viewport Resizer下载 谷歌前端自适应开发工具 在前端开发过程中,随 ...
- SQL联合查询中的关键语法(转)
联合查询效率较高.以下例子来说明联合查询的好处 t1表结构(用户名,密码) userid int username varchar(20) password ...