bzoj 3052: [wc2013]糖果公园 带修改莫队
3052: [wc2013]糖果公园
Time Limit: 250 Sec Memory Limit: 512 MB
Submit: 506 Solved: 189
[Submit][Status]
Description
Input
Output
Sample Input
Sample Input
Sample Output
131
27
84
HINT
本来这道题想到了莫队算法,但是看到带修改就直接放弃了。结果看题解才发现带修改居然也能用莫队!!!之所以可以这样用,是因为修改的时间复杂度非常非常低,以至于可以在修改的时间轴上任意跳跃。具体细节自己去看其他题解啦。
写的有点长,但是跑的还算比较快。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAXN 100100
#define MAXB 2200
#define MAXQ 100100
#define MAXV MAXN
#define MAXE MAXV*2
typedef long long qword;
inline int nextInt()
{
register int x=;
register int ch;
while (ch=getchar(),ch<'' || ch>'');
while (x=x*+ch-'',ch=getchar(),ch<='' && ch>='');
return x;
}
int n,m,q,sb;
struct Edge
{
int np;
Edge *next;
}E[MAXE],*V[MAXV];
int tope=-;
int que[MAXN];
void addedge(int x,int y)
{
E[++tope].np=y;
E[tope].next=V[x];
V[x]=&E[tope];
}
int depth[MAXN];
int pnt[MAXN];
int top[MAXN],bsiz[MAXN];
int belong[MAXN];
int topb=;
void bfs1()
{
Edge *ne;
int now;
int head=-,tail=;
que[]=;
pnt[]=;
belong[]=++topb;
top[]=;
bsiz[]=;
depth[]=;
while (head<tail)
{
now=que[++head];
for (ne=V[now];ne;ne=ne->next)
{
if (ne->np==pnt[now])continue;
que[++tail]=ne->np;
pnt[ne->np]=now;
depth[ne->np]=depth[now]+;
if (bsiz[belong[now]]<sb)
{
bsiz[belong[now]]++;
belong[ne->np]=belong[now];
top[ne->np]=top[now];
}else
{
belong[ne->np]=++topb;
bsiz[topb]=;
top[ne->np]=ne->np;
}
}
}
}
int jump[][MAXN];
void init_lca()
{
for (int i=;i<=n;i++)
jump[][i]=pnt[i];
for (int j=;j<;j++)
for (int i=;i<=n;i++)
jump[j][i]=jump[j-][jump[j-][i]];
}
int lca(int x,int y)
{
if (depth[x]<depth[y])swap(x,y);
int dep=depth[x]-depth[y];
for (int i=;i<;i++)
if (dep & (<<i))
x=jump[i][x];
if (x==y)return x;
for (int i=;i>=;i--)
if (jump[i][x]!=jump[i][y])
x=jump[i][x],y=jump[i][y];
return pnt[x];
}
int get_dis(int x,int y)
{
return depth[x]+depth[y]-*depth[lca(x,y)];
}
struct qur_t
{
int s,t,id;
int upper_pos;
qword ans;
}qur[MAXQ];
int topq=-;
bool cmp_qur_block(qur_t a1,qur_t a2)
{
if (belong[a1.s]!=belong[a2.s])
return belong[a1.s]<belong[a2.s];
if (belong[a1.t]!=belong[a2.t])
return belong[a1.t]<belong[a2.t];
return a1.id<a2.id;
}
bool cmp_qur_id(qur_t a1,qur_t a2)
{
return a1.id<a2.id;
}
int sweet[MAXN];
qword suprise[MAXN];
int candy[MAXN];
struct mdfy_t
{
int pos,cnew,cold,id;
}mdfy[MAXN];
int topm=-;
struct path
{
int s,t,a,ds;
path(int s,int t):s(s),t(t)
{
a=lca(s,t);
ds=depth[s]+depth[t]-*depth[a];
}
path(){}
bool inside(int x)
{
return get_dis(x,s)+get_dis(x,t)==ds;
}
void get_path(int *step,int &tops)
{
tops=-;
for (int x=s;x!=a;x=pnt[x])
step[++tops]=x;
tops=ds;
for (int x=t;x!=a;x=pnt[x])
step[tops--]=x;
step[tops--]=a;
tops=ds;
}
};
int tot[MAXN];
bool inside[MAXN];
int step[MAXN],tops;
int main()
{
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int x,y,z;
n=nextInt(),m=nextInt(),q=nextInt();
sb=pow(n,2.0/);
for (int i=;i<=m;i++)
sweet[i]=nextInt();
for (int i=;i<=n;i++)
suprise[i]=nextInt();
for (int i=;i<=n;i++)suprise[i]+=suprise[i-];
for (int i=;i<n;i++)
{
x=nextInt(),y=nextInt();
addedge(x,y);
addedge(y,x);
}
for (int i=;i<=n;i++)
candy[i]=nextInt();
int opt;
for (int i=;i<=q;i++)
{
opt=nextInt();
if (opt==)
{
x=nextInt(),y=nextInt();
++topm;
mdfy[topm].pos=x;
mdfy[topm].cnew=y;
mdfy[topm].cold=candy[x];
candy[x]=y;
mdfy[topm].id=i;
}else
{
x=nextInt(),y=nextInt();
++topq;
qur[topq].s=x;
qur[topq].t=y;
qur[topq].upper_pos=topm+;
qur[topq].id=i;
}
}
for (int i=topm;i>=;i--)
candy[mdfy[i].pos]=mdfy[i].cold;
bfs1();
init_lca();
sort(qur,qur+topq+,cmp_qur_block);
for (int i=;i<qur[].upper_pos;i++)
candy[mdfy[i].pos]=mdfy[i].cnew;
int a;
a=lca(qur[].s,qur[].t);
qword nsum=;
for (x=qur[].s;x!=a;x=pnt[x])
{
inside[x]=true;
tot[candy[x]]++;
nsum+=(suprise[tot[candy[x]]]-suprise[tot[candy[x]]-])*sweet[candy[x]];
}
for (y=qur[].t;;y=pnt[y])
{
inside[y]=true;
tot[candy[y]]++;
nsum+=(suprise[tot[candy[y]]]-suprise[tot[candy[y]]-])*sweet[candy[y]];
if (y==a)break;
}
qur[].ans=nsum;
path pnow(qur[].s,qur[].t);
path pwalk;
for (int i=;i<=topq;i++)
{
for (int kk=;kk<;kk++)
{
if (kk==)
pwalk=path(qur[i-].s,qur[i].s);
else
pwalk=path(qur[i-].t,qur[i].t);
pwalk.get_path(step,tops);
bool flag=true;
for (int j=;j<=tops+;j++)
{
if (j!=tops+ && inside[step[j]])
{
inside[step[j]]=false;
tot[candy[step[j]]]--;
nsum+=(suprise[tot[candy[step[j]]]]-suprise[tot[candy[step[j]]]+])*sweet[candy[step[j]]];
}else
{
if (flag)
{
inside[step[j-]]=true;
tot[candy[step[j-]]]++;
nsum+=(suprise[tot[candy[step[j-]]]]-suprise[tot[candy[step[j-]]]-])*sweet[candy[step[j-]]];
flag=false;
}
if (j==tops+)break;
inside[step[j]]=true;
tot[candy[step[j]]]++;
nsum+=(suprise[tot[candy[step[j]]]]-suprise[tot[candy[step[j]]]-])*sweet[candy[step[j]]];
}
}
}
if (qur[i-].upper_pos<qur[i].upper_pos)
{
for (int j=qur[i-].upper_pos;j<qur[i].upper_pos;j++)
{
if (candy[mdfy[j].pos]!=mdfy[j].cold)throw;
candy[mdfy[j].pos]=mdfy[j].cnew;
if (inside[mdfy[j].pos])
{
tot[mdfy[j].cold]--;
nsum+=(suprise[tot[mdfy[j].cold]]-suprise[tot[mdfy[j].cold]+])*sweet[mdfy[j].cold];
tot[mdfy[j].cnew]++;
nsum+=(suprise[tot[mdfy[j].cnew]]-suprise[tot[mdfy[j].cnew]-])*sweet[mdfy[j].cnew];
}
}
}else
{
for (int j=qur[i-].upper_pos-;j>=qur[i].upper_pos;j--)
{
if (candy[mdfy[j].pos]!=mdfy[j].cnew)throw;
candy[mdfy[j].pos]=mdfy[j].cold;
if (inside[mdfy[j].pos])
{
tot[mdfy[j].cnew]--;
nsum+=(suprise[tot[mdfy[j].cnew]]-suprise[tot[mdfy[j].cnew]+])*sweet[mdfy[j].cnew];
tot[mdfy[j].cold]++;
nsum+=(suprise[tot[mdfy[j].cold]]-suprise[tot[mdfy[j].cold]-])*sweet[mdfy[j].cold];
}
}
}
qur[i].ans=nsum;
}
sort(qur,qur+topq+,cmp_qur_id);
for (int i=;i<=topq;i++)
printf("%lld\n",qur[i].ans);
}
bzoj 3052: [wc2013]糖果公园 带修改莫队的更多相关文章
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
题目链接:BZOJ - 3052 题目分析 这道题就是非常经典的树上莫队了,并且是带修改的莫队. 带修改的莫队:将询问按照 左端点所在的块编号为第一关键字,右端点所在的块为第二关键字,位于第几次修改之 ...
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- 【bzoj3052】[wc2013]糖果公园 带修改树上莫队
题目描述 给出一棵n个点的树,每个点有一个点权,点权范围为1~m.支持两种操作:(1)修改一个点的点权 (2)对于一条路径,求$\sum\limits_{i=1}^m\sum\limits_{j=1} ...
- BZOJ.2453.维护队列([模板]带修改莫队)
题目链接 带修改莫队: 普通莫队的扩展,依旧从[l,r,t]怎么转移到[l+1,r,t],[l,r+1,t],[l,r,t+1]去考虑 对于当前所在的区间维护一个vis[l~r]=1,在修改值时根据是 ...
- 【BZOJ3052】[wc2013]糖果公园 带修改的树上莫队
[BZOJ3052][wc2013]糖果公园 Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 ...
- bzoj 2120: 数颜色【带修改莫队】
比较裸的带修莫队,对每个修改操作记一下它修改的位置修改前的颜色 然后正常莫队,每次对修改操作时间倒流一下即可 #include<iostream> #include<cstdio&g ...
- BZOJ 2120 数颜色 【带修改莫队】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2120 2120: 数颜色 Time Limit: 6 Sec Memory Limit: ...
- BZOJ 2120 数颜色(带修改莫队)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2120 [题目大意] 给出一颜色序列,每次可以修改一个位置的颜色或者询问一个区间不同颜色 ...
- BZOJ3052 [wc2013] 糖果公园 【树上莫队】
树上莫队和普通的序列莫队很像,我们把树进行dfs,然后存一个长度为2n的括号序列,就是一个点进去当作左括号,出来当作右括号,然后如果访问从u到v路径,我们可以转化成括号序列的区间,记录x进去的时候编号 ...
随机推荐
- 基于DOM的XSS注入漏洞简单解析
基于DOM的XSS注入漏洞简单解析http://automationqa.com/forum.php?mod=viewthread&tid=2956&fromuid=21
- IIS 返回 405 - 不允许用于访问此页的 HTTP 谓词。终极解决办法!!!!
首先这个问题在其他网站(CSDN,新浪博客等) 回答基本都是没有回答到"根本"上面来(而且总在纠结要不要勾选"全部谓词") 我是自己对比了本地IIS之后得出的结 ...
- modelsim脚本文件的编写
第一章 ModelSim介 绍 本指南是为 ModelSim5.5f版本编写的,该版本运行于UNIX和Microsoft Windows 95/98/Me/NT/2000的操作系统环境中.本指南覆盖了 ...
- react 资源汇总
前端变化虽快,但其实一直都围绕这几个概念在转: URL - 访问什么页面 Data - 显示什么信息 View - 页面长成什么样 Action - 对页面做了什么操作 API Server - Da ...
- cookie和session可能需要知道的知识
做Android程序员,了解服务器的知识是相当重要的,比如cookie和session. 首先介绍一点背景知识,我们知道HTTP的连接是无状态的,HTTPS只是增加了安全,有了SSL证书来验证,作为服 ...
- SQL Server调优系列进阶篇 - 查询优化器的运行方式
前言 前面我们的几篇文章介绍了一系列关于运算符的基础介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符. ...
- iOS 9 Spotlight搜索 OC版
介绍: 在WWDC 2015会议上,苹果官方公布了iOS9.除开许多新的特性和增强功能,这次升级也给了开发者们一个机会让他们的app里的内容能通过Spotlight 搜索功能被发现和使用.在iO ...
- iOS开发——文本高度
1.简单的计算文本高度 // 要计算的文本内容 NSString *testString = @"刘成利,软件工程专业毕业,iOS开发者,目前工作于北京,在证券金融领域从事iOS App开发 ...
- 二进制方式快速安装MySQL数据库命令集合
二进制方式快速安装MySQL数据库命令集合 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1.安装mysql ls mysql ...
- 【DP_树形DP专题】题单总结
转载自 http://blog.csdn.net/woshi250hua/article/details/7644959#t2 题单:http://vjudge.net/contest/123963# ...