【xsy2440】【GDOI2016】疯狂动物城



感受一下这恐怖的题目长度~~~
其实题意很裸,但是作为GDOI的一道防AK题,自然有他优秀的地方。
简化题意:给出一棵树,要求支持三个操作:
1.修改点值
2.询问点$x$到$y$之间的一些东东
3.回到某个版本之前
可持久化,强制在线。
考虑拆一下询问
如果把$x$到$y$路径上的所有点值放到一个数组$a$里,那么询问式子就是:
$\sum\limits_{i=1}^{n}a[i]\times\sum\limits_{j=1}^{n-i}j$
$=\sum\limits_{i=1}^{n}a[i]\times\frac{(n-i+1)\times(n-i)}{2}$
$=\sum\limits_{i=1}^{n}a[i]\times i^{2}-a[i]\times(2n+1)+a[i]\times n\times(n+1)$
发现$a[i]$,$a[i]\times i$,$a[i]\times i^2$都是常系数,于是就可以快乐维护了~
外面的很容易想到,树链剖分+可持久化线段树,单点修改即可。
可以感觉到逐渐膨胀的代码量>_<
注意到有左右方向的区别,要写两遍
代码量起飞了>_<
5000B刷新最长代码记录
注意:记得取模,随时爆int;
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define mod 20160501
using namespace std;
typedef long long ll;
struct edge{
int v,next;
}a[];
struct data{
ll s,a1,a2,s1,s2,ls,rs,lz,vv;
}t[];
ll n,m,u,v,w,ord,tim=,tot=,tote=,ans=,nrt=,nowrt=,last=,ans1[],ans2[],head[],rt[],num[],nmd[],dep[],top[],siz[],dfn[],son[],fa[];
void add(int u,int v){
a[++tote].v=v;
a[tote].next=head[u];
head[u]=tote;
}
void dfs1(int u,int f,int dpt){
fa[u]=f;
dep[u]=dpt;
siz[u]=;
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v==f)continue;
dfs1(v,u,dpt+);
siz[u]+=siz[v];
if(son[u]==-||siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int nowtp){
top[u]=nowtp;
dfn[u]=++tim;
nmd[tim]=u;
if(son[u]==-)return;
dfs2(son[u],nowtp);
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v==son[u]||v==fa[u])continue;
dfs2(v,v);
}
}
void pushup(int u){
t[u].s=(t[t[u].ls].s+t[t[u].rs].s)%mod;
t[u].a1=(t[t[u].ls].a1+t[t[u].rs].a1)%mod;
t[u].a2=(t[t[u].ls].a2+t[t[u].rs].a2)%mod;
t[u].s1=(t[t[u].ls].s1+t[t[u].rs].s1)%mod;
t[u].s2=(t[t[u].ls].s2+t[t[u].rs].s2)%mod;
}
void build(int l,int r,int u){
if(l==r){
t[u].s=num[nmd[l]];
t[u].a1=dep[nmd[l]];
t[u].a2=(t[u].a1*t[u].a1)%mod;
t[u].s1=(t[u].s*t[u].a1)%mod;
t[u].s2=(t[u].s*t[u].a2)%mod;
return;
}
int mid=(l+r)/;
build(l,mid,t[u].ls=++tot);
build(mid+,r,t[u].rs=++tot);
pushup(u);
}
void updata(int l,int r,int u,int L,int R,int lst,ll v){
if(u==tot)t[u]=t[lst];
if(l==L&&r==R){
t[u].ls=t[lst].ls;
t[u].rs=t[lst].rs;
t[u].lz=(t[u].lz+v)%mod;
t[u].s1=(t[u].s1+t[u].a1*v)%mod;
t[u].s2=(t[u].s2+t[u].a2*v)%mod;
t[u].s=(t[u].s+v*(r-l+))%mod;
t[u].vv=(t[u].vv+v)%mod;
return;
}
int mid=(l+r)/;
if(R<=mid){
if(t[u].rs<=last)t[u].rs=t[lst].rs;
if(t[u].ls<=last)t[u].ls=++tot;
updata(l,mid,t[u].ls,L,R,t[lst].ls,v);
}else if(mid<L){
if(t[u].ls<=last)t[u].ls=t[lst].ls;
if(t[u].rs<=last)t[u].rs=++tot;
updata(mid+,r,t[u].rs,L,R,t[lst].rs,v);
}else{
if(t[u].ls<=last)t[u].ls=++tot;
updata(l,mid,t[u].ls,L,mid,t[lst].ls,v);
if(t[u].rs<=last)t[u].rs=++tot;
updata(mid+,r,t[u].rs,mid+,R,t[lst].rs,v);
}
t[u].s1=(t[t[u].ls].s1+t[t[u].rs].s1+t[u].a1*t[u].vv%mod)%mod;
t[u].s2=(t[t[u].ls].s2+t[t[u].rs].s2+t[u].a2*t[u].vv%mod)%mod;
t[u].s=(t[t[u].ls].s+t[t[u].rs].s+t[u].vv*(r-l+)%mod)%mod;
}
void getans(int u,int b,ll lz,ll v){
ans=(ans+t[u].s2+lz*t[u].a2%mod)%mod;
ans1[b]=(ans1[b]+t[u].s1+t[u].a1*lz%mod)%mod;
ans2[b]=(ans2[b]+t[u].s+v*lz%mod)%mod;
}
void query(int l,int r,int u,int L,int R,int b,ll lz){
if(!u)return;
lz+=t[u].vv;
if(l==L&&r==R){
lz-=t[u].lz;
getans(u,b,lz,r-l+);
return;
}
int mid=(l+r)/;
if(R<=mid)query(l,mid,t[u].ls,L,R,b,lz);
else if(mid<L)query(mid+,r,t[u].rs,L,R,b,lz);
else{
query(l,mid,t[u].ls,L,mid,b,lz);
query(mid+,r,t[u].rs,mid+,R,b,lz);
}
}
void work(int t,int t1,int u,int v,ll w){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
updata(,n,rt[t],dfn[top[u]],dfn[u],rt[t1],w);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
updata(,n,rt[t],dfn[u],dfn[v],rt[t1],w);
}
int work1(int t,int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]>dep[top[v]]){
query(,n,rt[t],dfn[top[u]],dfn[u],,);
u=fa[top[u]];
}else{
query(,n,rt[t],dfn[top[v]],dfn[v],,);
v=fa[top[v]];
}
}
if(dep[u]>dep[v]){
query(,n,rt[t],dfn[v],dfn[u],,);
return v;
}else{
query(,n,rt[t],dfn[u],dfn[v],,);
return u;
}
}
int main(){
memset(son,-,sizeof(son));
memset(head,-,sizeof(head));
scanf("%lld%lld",&n,&m);
for(int i=;i<n;i++){
scanf("%lld%lld",&u,&v);
add(u,v);
add(v,u);
}
for(int i=;i<=n;i++)scanf("%lld",&num[i]);
dfs1(,,);
dfs2(,);
rt[]=tot=;
build(,n,rt[]);
for(int i=;i<=m;i++){
scanf("%lld",&ord);
if(ord==){
scanf("%lld%lld%lld",&u,&v,&w);
u^=ans;
v^=ans;
last=tot;
rt[++nrt]=++tot;
work(nrt,nowrt,u,v,w);
nowrt=nrt;
}else if(ord==){
scanf("%lld%lld",&u,&v);
u^=ans;
v^=ans;
ans=ans1[]=ans1[]=ans2[]=ans2[]=;
int t=dep[v]-dep[work1(nowrt,u,v)]*;
ans=(ans+ans1[]*(t*+)%mod+ans2[]*t%mod*(t+)%mod)%mod;
ans=(ans-ans1[]*(dep[v]*+)%mod+ans2[]*dep[v]%mod*(dep[v]+)%mod+mod)%mod;
ans=(ans*)%(ll)mod;
ans=(ans+mod)%mod;
printf("%lld\n",ans);
}else{
scanf("%lld",&u);
u^=ans;
nowrt=u;
}
}
return ;
}
【xsy2440】【GDOI2016】疯狂动物城的更多相关文章
- 《疯狂动物城》主题曲《TryEverything》中文翻译
<疯狂动物城>主题曲<TryEverything>夏奇拉激情献唱,很多事情是需要是试试,不试试就不知道可以成功. Oh oh oh oh oooh 哦哦哦哦哦 Oh oh oh ...
- [GDOI2016][树链剖分+主席树]疯狂动物城
题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...
- COGS-2049 疯狂动物城
Description 你意外来到了一个未知的星球, 这里是一个动物乌托邦, 生活着一群拥有非凡智力的动物. 你遇到了一个叫做尼克的狐狸, 他准备给他的 GF 过生日 . 他将制作一个巨大的多层蛋糕, ...
- 【GDOI 2016 Day1】疯狂动物城
题目 分析 注意注意:码农题一道,打之前做好心理准备. 对于操作1.2,修改或查询x到y的路径,显然树链剖分. 对于操作2,我们将x到y的路径分为x到lca(x,y)和lca(x,y)到y两部分. 对 ...
- [GDOI2016] 疯狂动物园 [树链剖分+可持久化线段树]
题面 太长了,而且解释的不清楚,我来给个简化版的题意: 给定一棵$n$个点的数,每个点有点权,你需要实现以下$m$个操作 操作1,把$x$到$y$的路径上的所有点的权值都加上$delta$,并且更新一 ...
- GDOI2016酱油记(补发)
这篇酱油记是前年发在MCHacker一个叫code-hub的博客上的(已崩),现在来补发一下... GDOI2016扯淡(爆零记) 大家好,我是巨弱DCDCBigBig,在五一期间和一群神牛去考GDO ...
- 【IOS】将一组包含中文的数据按照#ABC...Z✿分组
上一篇文章[IOS]模仿windowsphone列表索引控件YFMetroListBox里面 我们一步步的实现了WindowsPhone风格的索引. 但是有没有发现,如果你要实现按照字母排序,你还得自 ...
- 可变数组NSMutableArray
//创建一个空的可变数组 NSMutableArray *array = [NSMutableArray array]; //向数组里面添加对象 [array addObject:@"< ...
- spring笔记--依赖注入之针对不同类型变量的几种注入方式
控制反转和依赖注入讲的都是一个概念,只不过是站在了不同的角度,所谓的依赖注入: 是指在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bea ...
随机推荐
- Stack Overflow大揭密:哪一种程序员工资最高?
Stackoverflow在程序员之间可以說是无人不知无人不晓,甚至常有人开玩笑说:“如果stackoverflow倒闭了,全世界代码的产出率将下降一半以上”或许听起来有点夸张,但是不难想像这个网站在 ...
- CDR 2017压感笔和压感设备该怎么设置使用?
您可以通过CorelDRAW 2017 中的以下工具来运用压感笔.笔或其他设备的压力:艺术笔(表达模式).橡皮擦.涂抹.转动.吸引.排斥.粗糙和弄脏.此外,您还可以通过艺术笔(表达模式)工具.橡皮擦. ...
- Codeforces Round #499 (Div. 2) F. Mars rover_dfs_位运算
题解: 首先,我们可以用 dfsdfsdfs 在 O(n)O(n)O(n) 的时间复杂度求出初始状态每个点的权值. 不难发现,一个叶子节点权值的取反会导致根节点的权值取反当且仅当从该叶子节点到根节点这 ...
- CF1041F Ray in the tube构造_思维
不难发现起点必定是一个点. 每次间隔的距离一定是 2k2^k2k,关键就是要判断两点是否在同一跳跃距离上可被同时覆盖. 我们可以对上边进行 x1≡x_{1}\equivx1≡ x2mod(2∗dx) ...
- Python笔记27----时间解析
1.将时间字符串解析成真正的时间 time.strptime http://www.runoob.com/python/att-time-strptime.html 代码: import time s ...
- CSS的引入方式和样式
CSS的引入方式和样式 一.样式 行内样式 内接样式 外接样式(1.链接式 2.导入式) <!--行内样式--> <div> <p style="color: ...
- W10子系统UBantu命令安装Redis及其启动
W10子系统UBantu命令安装Redis及其启动 打开W10子系统UBantu 安装Redis $sudo apt-get install redis-server 启动Redis redis-se ...
- JDK+JDBC+MySQL实例及注意事项
by qx.zhong Hangzhou 29 Jun 2014 开发环境 OS: Win8.1 x64 JDK: 1.8 SE DB: MySQL 5.5 Lib: mysql-connec ...
- Aizu - 2306 Rabbit Party (DFS图论)
G. Rabbit Party Time Limit: 5000ms Case Time Limit: 5000ms Memory Limit: 65536KB 64-bit integer IO f ...
- Detours改动段属性漏洞
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...