【GDOI 2016 Day1】疯狂动物城
题目
分析
注意注意:码农题一道,打之前做好心理准备。
对于操作1、2,修改或查询x到y的路径,显然树链剖分。
对于操作2,我们将x到y的路径分为x到lca(x,y)和lca(x,y)到y两部分。
对于第一部分的某个点i,设它到y的距离为s,那么s=deep[i]+deep[y]-2*deep[lca(x,y)],i对答案的贡献为a[i]s(s+1)/2,如果不考虑除以2,设t=deep[y]-2*deep[lca(x,y)],则贡献为a[i]*deep[i]2+a[i]*deep[i]*(2*t+1)+a[i]*(t+t2)。
对于第二部分的点i,s=deep[y]-deep[i],设lca(x,y),则贡献为a[i]*deep[i]2-a[i]*deep[i]*(2*t+1)+a[i]*(t+t2)。
接着,对于每个点i我们就用线段树来维护a[i]*deep[i]^2、a[i]*deep[i]以及a[i]。
注意:最后记得除2,由于mod 20160501,用逆元。还有,lca(x,y)的贡献会重复,要减掉重复的。
对于操作3,打个可持久化线段树。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=20160501;
using namespace std;
struct trees
{
long long lazy,l,r;
long long v1;//a[i]*deep[i]^2
long long v2;//a[i]*deep[i]
long long v3;//a[i]
long long d;
long long d2;
}tree[7000000];
long long g[200005][25],d[200005],son[200005],deep[200005],size[200005],fa[200005],top[200005],bef[200005],f[220005];
long long last[200005],next[200005],to[200005];
long long n,m,ans,t,po,tot,tt;
long long bj(long long x,long long y)
{
next[++tot]=last[x];
last[x]=tot;
to[tot]=y;
}
long long premi()
{
for(long long j=1;j<=log2(n);j++)
{
for(long long i=1;i<=n;i++)
{
g[i][j]=g[g[i][j-1]][j-1];
}
}
}
long long build(long long x)
{
size[x]=1;
g[x][0]=fa[x];
long long mx=0;
for(long long i=last[x];i;i=next[i])
{
long long j=to[i];
if(j!=fa[x])
{
fa[j]=x;
deep[j]=deep[x]+1;
build(j);
size[x]+=size[j];
if(size[j]>mx)
{
mx=size[j];
son[x]=j;
}
}
}
}
long long build1(long long x)
{
d[++tot]=x;
bef[x]=tot;
if(!top[x])
{
top[x]=x;
}
if(son[x])
{
top[son[x]]=top[x];
build1(son[x]);
}
for(long long i=last[x];i;i=next[i])
{
long long j=to[i];
if(j!=fa[x] && son[x]!=j)
{
build1(j);
}
}
}
long long bnew(long long v,long long l,long long r,long long e)
{
if(l==r)
{
tree[v].lazy=0;
return 0;
}
long long mid=(l+r)/2;
if(e!=2)
{
tree[++tot]=tree[tree[v].l];
if(e==3)
{
tree[tot].v1=(tree[tot].v1+tree[v].lazy*tree[tot].d2)%mo;
tree[tot].v2=(tree[tot].v2+tree[v].lazy*tree[tot].d)%mo;
tree[tot].v3=(tree[tot].v3+tree[v].lazy*(mid-l+1))%mo;
tree[tot].lazy=(tree[tot].lazy+tree[v].lazy)%mo;
}
tree[v].l=tot;
}
if(e>=2)
{
tree[++tot]=tree[tree[v].r];
if(e==3)
{
tree[tot].v1=(tree[tot].v1+tree[v].lazy*tree[tot].d2)%mo;
tree[tot].v2=(tree[tot].v2+tree[v].lazy*tree[tot].d)%mo;
tree[tot].v3=(tree[tot].v3+tree[v].lazy*(r-(mid+1)+1))%mo;
tree[tot].lazy=(tree[tot].lazy+tree[v].lazy)%mo;
}
tree[v].r=tot;
}
tree[v].lazy=0;
}
long long change1(long long v,long long l,long long r,long long x,long long value)
{
if(l==r)
{
tree[v].v3=value;
tree[v].v2=value*deep[d[l]];
tree[v].v1=value*deep[d[l]]*deep[d[l]];
tree[v].d=deep[d[l]];
tree[v].d2=deep[d[l]]*deep[d[l]];
return 0;
}
long long mid=(l+r)/2;
if(x<=mid)
{
if(!tree[v].l) tree[v].l=++tot;
change1(tree[v].l,l,mid,x,value);
}
else
{
if(!tree[v].r) tree[v].r=++tot;
change1(tree[v].r,mid+1,r,x,value);
}
tree[v].v1=tree[tree[v].l].v1+tree[tree[v].r].v1;
tree[v].v2=tree[tree[v].l].v2+tree[tree[v].r].v2;
tree[v].v3=tree[tree[v].l].v3+tree[tree[v].r].v3;
tree[v].d=tree[tree[v].l].d+tree[tree[v].r].d;
tree[v].d2=tree[tree[v].l].d2+tree[tree[v].r].d2;
}
long long change(long long v,long long l,long long r,long long x,long long y,long long value)
{
if(l==x && r==y)
{
tree[v].v1=tree[v].v1+value*tree[v].d2;
tree[v].v2=tree[v].v2+value*tree[v].d;
tree[v].v3=tree[v].v3+value*(r-l+1);
tree[v].lazy=tree[v].lazy+value;
return 0;
}
bool bz=true;
if(tree[v].lazy)
{
bnew(v,l,r,3);
bz=false;
}
long long mid=(l+r)/2;
if(y<=mid)
{
if(bz) bnew(v,l,r,1);
change(tree[v].l,l,mid,x,y,value);
}
else
if(x>=mid+1)
{
if(bz) bnew(v,l,r,2);
change(tree[v].r,mid+1,r,x,y,value);
}
else
{
if(bz) bnew(v,l,r,4);
change(tree[v].l,l,mid,x,mid,value);
change(tree[v].r,mid+1,r,mid+1,y,value);
}
tree[v].v1=tree[tree[v].l].v1+tree[tree[v].r].v1;
tree[v].v2=tree[tree[v].l].v2+tree[tree[v].r].v2;
tree[v].v3=tree[tree[v].l].v3+tree[tree[v].r].v3;
}
long long lca(long long x,long long y)
{
if(deep[x]>deep[y])
{
x=x^y;
y=x^y;
x=x^y;
}
for(long long i=log2(n);i>=0;i--)
{
if(deep[g[y][i]]>deep[x])
y=g[y][i];
}
if(deep[y]!=deep[x]) y=g[y][0];
for(long long i=log2(n);i>=0;i--)
{
if(g[y][i]!=g[x][i])
{
y=g[y][i];
x=g[x][i];
}
}
if(x!=y) y=g[y][0];
return y;
}
long long find(long long v,long long l,long long r,long long x,long long y,long long value,long long o)
{
if(l==x && r==y)
{
return ((tree[v].v1+o*tree[v].v2*(2*value+1)+tree[v].v3*(value+value*value))%mo+mo)%mo;
}
if(tree[v].lazy)
{
bnew(v,l,r,3);
}
long long mid=(l+r)/2,e=0;
if(y<=mid)
{
e=find(tree[v].l,l,mid,x,y,value,o);
}
else
if(x>=mid+1)
{
e=find(tree[v].r,mid+1,r,x,y,value,o);
}
else
{
e=find(tree[v].l,l,mid,x,mid,value,o)+find(tree[v].r,mid+1,r,mid+1,y,value,o);
}
tree[v].v1=tree[tree[v].l].v1+tree[tree[v].r].v1;
tree[v].v2=tree[tree[v].l].v2+tree[tree[v].r].v2;
tree[v].v3=tree[tree[v].l].v3+tree[tree[v].r].v3;
return e;
}
long long work(long long x,long long y,long long z)
{
if(z)
{
f[++t]=++tot;
tree[tot]=tree[f[tt]];
tt=t;
while(top[x]!=top[y])
{
if(deep[top[x]]>=deep[top[y]])
{
change(f[t],1,n,bef[top[x]],bef[x],z);
x=fa[top[x]];
}
else
{
change(f[t],1,n,bef[top[y]],bef[y],z);
y=fa[top[y]];
}
}
if(deep[x]>=deep[y])
{
change(f[t],1,n,bef[y],bef[x],z);
}
else
{
change(f[t],1,n,bef[x],bef[y],z);
}
}
else
{
ans=0;
long long lc=lca(x,y),xx=x,yy=y;
long long p=deep[yy]-deep[lc]*2;
x=xx;
y=lc;
if(x!=y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]>=deep[top[y]])
{
ans=((ans+find(f[tt],1,n,bef[top[x]],bef[x],p,1))%mo+mo)%mo;
x=fa[top[x]];
}
else
{
ans=((ans+find(f[tt],1,n,bef[top[y]],bef[y],p,1))%mo+mo)%mo;
y=fa[top[y]];
}
}
if(deep[x]>=deep[y])
{
ans=((ans+find(f[tt],1,n,bef[y],bef[x],p,1))%mo+mo)%mo;
}
else
{
ans=((ans+find(f[tt],1,n,bef[x],bef[y],p,1))%mo+mo)%mo;
}
if(lc!=yy) ans=((ans-find(f[tt],1,n,bef[lc],bef[lc],p,1))%mo+mo)%mo;
}
x=lc;
y=yy;
p=deep[yy];
if(x!=y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]>=deep[top[y]])
{
ans=((ans+find(f[tt],1,n,bef[top[x]],bef[x],p,-1))%mo+mo)%mo;
x=fa[top[x]];
}
else
{
ans=((ans+find(f[tt],1,n,bef[top[y]],bef[y],p,-1))%mo+mo)%mo;
y=fa[top[y]];
}
}
if(deep[x]>=deep[y])
{
ans=((ans+find(f[tt],1,n,bef[y],bef[x],p,-1))%mo+mo)%mo;
}
else
{
ans=((ans+find(f[tt],1,n,bef[x],bef[y],p,-1))%mo+mo)%mo;
}
}
ans=(ans%mo+mo)*10080251%mo;
printf("%lld\n",ans);
}
}
int main()
{
scanf("%lld%lld",&n,&m);
for(long long i=1;i<=n-1;i++)
{
long long x,y;
scanf("%lld%lld",&x,&y);
bj(x,y);
bj(y,x);
}
tot=0;
deep[1]=1;
build(1);
build1(1);
tot=1;
f[0]=1;
t=0;
tt=0;
for(long long i=1;i<=n;i++)
{
long long x;
scanf("%lld",&x);
change1(1,1,n,bef[i],x);
}
premi();
ans=0;
for(long long i=1;i<=m;i++)
{
long long p,x,y,z;
scanf("%lld",&p);
if(p==1)
{
scanf("%lld%lld%lld",&x,&y,&z);
work(x^ans,y^ans,z);
}
else
if(p==2)
{
scanf("%lld%lld",&x,&y);
work(x^ans,y^ans,0);
}
else
{
scanf("%lld",&x);
tt=x^ans;
}
}
}
【GDOI 2016 Day1】疯狂动物城的更多相关文章
- 《疯狂动物城》主题曲《TryEverything》中文翻译
<疯狂动物城>主题曲<TryEverything>夏奇拉激情献唱,很多事情是需要是试试,不试试就不知道可以成功. Oh oh oh oh oooh 哦哦哦哦哦 Oh oh oh ...
- [GDOI2016][树链剖分+主席树]疯狂动物城
题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...
- COGS-2049 疯狂动物城
Description 你意外来到了一个未知的星球, 这里是一个动物乌托邦, 生活着一群拥有非凡智力的动物. 你遇到了一个叫做尼克的狐狸, 他准备给他的 GF 过生日 . 他将制作一个巨大的多层蛋糕, ...
- 【xsy2440】【GDOI2016】疯狂动物城
感受一下这恐怖的题目长度~~~ 其实题意很裸,但是作为GDOI的一道防AK题,自然有他优秀的地方. 简化题意:给出一棵树,要求支持三个操作: 1.修改点值 2.询问点$x$到$y$之间的一些东东 3. ...
- 【GDOI 2016 Day1】第二题 最长公共子串
分析 首先,可以发现,区间是可以合并滴.把区间按左端点排序,对于两个区间[l1,r1].[l2,r2],当l1<=l2 and r1>=l2,那么,将它们合成一个新的区间[l1,r2].当 ...
- https://docs.huihoo.com/infoq/qconbeijing/2016/day1/工程效率提升专题/2-2-支持百度万人开发的工具装备及百度工程能力建设-夏仲璞.pdf
https://docs.huihoo.com/infoq/qconbeijing/2016/day1/工程效率提升专题/2-2-支持百度万人开发的工具装备及百度工程能力建设-夏仲璞.pdf http ...
- GDOI 2016 & APIO 2016 游记
缓慢施工中...... UPD:APIO游记已烂尾......因为Cu滚粗+生病一直没心情写..过了几天就发现APIO的事都快忘光了...去看KPM的就可以啦 今年apio竟然没和gdoi撞...智障 ...
- Noip 2016 Day1 题解
老师让我们刷历年真题, 然后漫不经心的说了一句:“你们就先做做noip2016 day1 吧” ...... 我还能说什么,,,,,老师你这是明摆着伤害我们啊2333333333 预计分数:100+2 ...
- noip 2016 day1 T1玩具谜题
题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉 ...
随机推荐
- 开发一个Flink应用
步骤列表本次实战经历以下步骤: 创建应用:编码:构建:提交任务到Flink,验证功能: 环境信息Flink:1.7:Flink所在机器的操作系统:CentOS Linux release 7.5.18 ...
- jmeter之报告输出(html)
在使用jmeter进行测试时,我们需要生成相应的测试报告,jmeter3.0之后有自带的测试报告. 在测试报告的格式和输出内容不满足需求时,我们可以根据需要去修改其配置文件(jmeter.proper ...
- 系统分析与设计HW6
1. 使用 UML State Model建模 建模对象: 参考 Asg_RH 文档, 对 Reservation/Order 对象建模. 建模要求: 参考练习不能提供足够信息帮助你对订单对象建模,请 ...
- RESR API (一)之Requests
Requests 如果您正在做基于REST的Web服务,您应该忽略request.POST. - Malcom Tredinnick,Django开发团队 REST框架的Request类扩展了标准的H ...
- C 语言中的关键字 - 数据类型、数据修饰符及逻辑结构
C 语言中有 32 个关键字.这是留个编译器用的特殊字符串,用户不可以使用. 特殊关键字 sizeof 和 return 是 C 语言中的两个特殊关键字. sizeof sizeof 用于计算变量所占 ...
- Nginx 配置文件 nginx.conf 详解
Nginx的配置文件nginx.conf配置详解如下: user nginx nginx; #Nginx用户及组:用户 组.window下不指定 worker_processes 8; #工作进程:数 ...
- Time Series Anomaly Detection
这里有个2015年的综述文章,概括的比较好,各种技术的适用场景. https://iwringer.wordpress.com/2015/11/17/anomaly-detection-concep ...
- 所遇Oracle错误代码
ORA-00905: 缺失关键字 少了空格或关键字写错 ORA-00922: 选项缺失或无效 错误原因:一般是语句的语法有问题.比如命名不对,关键字写错等等.对于非标准的命名,一般采用双引号来创建 ...
- win10远程桌面报出现身份验证错误,要求的函数不受支持
win10远程桌面报出现身份验证错误,要求的函数不受支持 编写人:左丘文 2019-6-6 公司换了一台新笔记本电脑,是win10操作系统,刚想远程连接一下服务器,发现以前很正常的功能,发现不行了.网 ...
- 破解mysql
https://blog.csdn.net/lian_easel/article/details/78734240 破解mysql