题目

有三个操作:

  • \(change \ u \ v \ a \ b\) : \(u\)到\(v\)路径上的点点权加上\(a+k*b\),\(k\)为第几个点,\(u\)为第0个点。
  • \(query \ u \ v\) : 询问\(u\)到\(v\)路径上的点权和。
  • \(roll \ w\) : 回到第\(w\)个\(change\)之后的状态。

强制在线。

分析

会写树剖啦!会写树剖啦!会写树剖啦!

当时没怎么看这题,一直在写前面的计算几何。其实这题也很简单,轻重链剖分加主席树即可。关键在于如何解决加上点权和查询的操作。我们发现加上的点权是一个等差数列。

开始之考虑一个标记,\(a\)和\(b\),那么如果一个区间是\([l,r]\),那么区间和为:

\[a * (r-l+1)+\frac {b*(r-l)*(r-l+1)}{2}
\]

我们发现,标记的运算只和\(l\)和\(r\)有关,并且同一个区间是一样的,于是对于每个区间,它的\(a\)和\(b\)可以直接累加,标记不下传。

写主席树的时候,可以给每个点打个标记,看看这个点是不是这一个时间点的,如果不是才新建。之前可持久化并查集也是一样的。

代码

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#define open(x) (((x)+ans)%n+1)
#define F(x) for (giant i=h[x],v=e[i].v;i;i=e[i].nxt,v=e[i].v)
using namespace std;
typedef long long giant;
giant read() {
giant x=0,f=1;
char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const giant maxn=1e5+10;
const giant maxj=18;
const giant nlogn=1<<23;
giant n,last;
giant ans=0,total=0;
struct edge {
giant v,nxt;
} e[maxn<<1];
giant h[maxn],tot=0,tim=0,root[maxn];
void add(giant u,giant v) {
e[++tot]=(edge){v,h[u]};
h[u]=tot;
}
giant top[maxn],size[maxn],son[maxn],first[maxn],second[maxn],dfn=0;
giant dep[maxn],father[maxn][maxj];
giant tic[nlogn],tt=0;
struct node {
giant lc,rc,ta,tb,sum;
} t[nlogn];
giant lca(giant x,giant y) {
if (dep[x]<dep[y]) swap(x,y);
for (giant j=maxj-1;j>=0;--j) if (dep[father[x][j]]>=dep[y]) x=father[x][j];
if (x==y) return x;
for (giant j=maxj-1;j>=0;--j) if (father[x][j]!=father[y][j]) x=father[x][j],y=father[y][j];
return father[x][0];
}
void dfs(giant x,giant fa) {
size[x]=1;
dep[x]=dep[fa]+1;
father[x][0]=fa;
giant ma=0,&id=son[x];
F(x) if (v!=fa) {
dfs(v,x);
size[x]+=size[v];
if (size[v]>ma) ma=size[v],id=v;
}
}
void build(giant x,giant fa,giant tp) {
if (!x) return;
first[x]=++dfn;
top[x]=tp;
build(son[x],x,tp);
F(x) if (v!=fa && v!=son[x]) build(v,x,v);
second[x]=dfn;
}
void modify(giant &x,giant rt,giant L,giant R,giant l,giant r,giant thea,giant theb) {
if (tic[x]!=tim) x=++tt,tic[x]=tim,t[x]=t[rt];
if (L==l && R==r) {
t[x].ta+=thea;
t[x].tb+=theb;
t[x].sum+=(R-L)*(R-L+1)/2*theb+(R-L+1)*thea;
return;
}
giant mid=(L+R)>>1;
if (r<=mid) modify(t[x].lc,t[rt].lc,L,mid,l,r,thea,theb); else
if (l>mid) modify(t[x].rc,t[rt].rc,mid+1,R,l,r,thea,theb); else {
modify(t[x].lc,t[rt].lc,L,mid,l,mid,thea,theb);
modify(t[x].rc,t[rt].rc,mid+1,R,mid+1,r,thea+(mid-l+1)*theb,theb);
}
t[x].sum=t[t[x].lc].sum+t[t[x].rc].sum+(R-L)*(R-L+1)/2*t[x].tb+(R-L+1)*t[x].ta;
}
giant query(giant x,giant L,giant R,giant l,giant r) {
if (L==l && R==r) return t[x].sum;
giant len=r-l;
giant ret=(2*t[x].ta+(l+r-L*2)*t[x].tb)*(r-l+1)/2;
giant mid=(L+R)>>1;
if (r<=mid) ret+=query(t[x].lc,L,mid,l,r); else
if (l>mid) ret+=query(t[x].rc,mid+1,R,l,r); else {
ret+=query(t[x].lc,L,mid,l,mid);
ret+=query(t[x].rc,mid+1,R,mid+1,r);
}
return ret;
}
giant jump(giant x,giant y) {
for (giant j=0;j<maxj;++j) if (y&(1<<j)) x=father[x][j];
return x;
}
void change(giant u,giant v,giant a,giant b) {
giant l=lca(u,v),utl=dep[u]-dep[l],x;
for (x=u;dep[top[x]]>dep[l];x=father[top[x]][0]) {
giant thea=a+b*(dep[u]-dep[top[x]]);
giant theb=-b;
modify(root[tim],last,1,n,first[top[x]],first[x],thea,theb);
}
if (dep[x]>=dep[l]) {
giant thea=a+b*(dep[u]-dep[l]);
giant theb=-b;
modify(root[tim],last,1,n,first[l],first[x],thea,theb);
}
for (x=v;dep[top[x]]>dep[l];x=father[top[x]][0]) {
giant thea=a+b*(utl+dep[top[x]]-dep[l]);
giant theb=b;
modify(root[tim],last,1,n,first[top[x]],first[x],thea,theb);
}
if (dep[x]>dep[l]) {
giant tmp=jump(x,dep[x]-dep[l]-1);
giant thea=a+b*(utl+dep[tmp]-dep[l]);
giant theb=b;
modify(root[tim],last,1,n,first[tmp],first[x],thea,theb);
}
giant thea=a+utl*b,theb=-b;
}
giant ask(giant u,giant v) {
giant l=lca(u,v),x,ret=0;
for (x=u;dep[top[x]]>dep[l];x=father[top[x]][0]) {
ret+=query(last,1,n,first[top[x]],first[x]);
}
if (dep[x]>=dep[l]) {
ret+=query(last,1,n,first[l],first[x]);
}
for (x=v;dep[top[x]]>dep[l];x=father[top[x]][0]) {
ret+=query(last,1,n,first[top[x]],first[x]);
}
if (dep[x]>dep[l]) {
int tmp=jump(x,dep[x]-dep[l]-1);
ret+=query(last,1,n,first[tmp],first[x]);
}
return ret;
}
void print(giant x) {
if (!x) {
puts("0");
return;
}
static char s[20];
int tot=0;
while (x) s[++tot]=x%10+'0',x/=10;
while (tot--) putchar(s[tot+1]);
puts("");
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("my.out","w",stdout);
#endif
n=read();
giant m=read();
for (giant i=1;i<n;++i) {
giant u=read(),v=read();
add(u,v),add(v,u);
}
dfs(1,0);
build(1,0,1);
for (giant j=1;j<maxj;++j) for (giant i=1;i<=n;++i) father[i][j]=father[father[i][j-1]][j-1];
int test=0;
while (m--) {
static char o[10];
scanf("%s",o);
if (o[0]=='c') {
giant u=open(read()),v=open(read());
giant a=read(),b=read();
++total,++tim;
root[tim]=last;
change(u,v,a,b);
last=root[tim];
} else if (o[0]=='q') {
giant u=open(read()),v=open(read());
ans=ask(u,v);
print(ans);
} else if (o[0]=='r') {
last=root[(read()+ans)%(total+1)];
}
}
}

Version的更多相关文章

  1. ASP.NET Core: You must add a reference to assembly mscorlib, version=4.0.0.0

    ASP.NET Core 引用外部程序包的时候,有时会出现下面的错误: The type 'Object' is defined in an assembly that is not referenc ...

  2. java -version 问题

    我把 JAVA_HOME 从8改成了 7 , 为什么还是 显示的8啊 ! E:\sv0\jars>java -version java version "1.8.0_111" ...

  3. 记一次jdk升级引起的 Unsupported major.minor version 51.0

    之前jdk 一直是1.6,tomcat 是6.x 版本,, 现在引入的新的jar, 出现 Caused by: java.lang.UnsupportedClassVersionError: org/ ...

  4. Java–cvc-complex-type.4:Attribut ‘version’ must appear on element ‘web-app’

    问题解析: 在web.xml中的以下代码中 <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi=" ...

  5. 在idea中maven项目jdk编译version总是跳到1.5

    bug描述 项目ide: idea 项目构建工具:maven bug现象:每次修改pom之后,idea自动扫描一遍,然后发现默认的compile级别跳到5.0. 每次手动去setting里修改comp ...

  6. 未能加载文件或程序集“Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5”或它的某一个依赖项。系统找不到指定的文件。

    在创建ASP.NET MVC项目过程中发生了这个异常 未能加载文件或程序集"Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0 ...

  7. 无法解决“Microsoft.SharePoint.Security, Version=15.0.0.0,”与“Microsoft.SharePoint.Security, Version=14.0.0.0”之间的冲突

    VisualStudio 2013创建控制台项目,.NetFramework选为4.5.生成目标平台:x64.然后添加对Microsoft.SharePoint.dll的引用. 生成项目时," ...

  8. Newtonsoft.Json, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b9a188c8922137c6

    未能加载文件或程序集“Newtonsoft.Json, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b9a188c8922137c6”或它的某一个 ...

  9. 未能加载文件或程序集“System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。系统找不到指定的文件

    ASP.NET 运行时错误:针对类型System.Web.Mvc.PreApplicationStartCode的应用程序邓启动初始化方法Start 引发了异常,显示下列错误消息: 未能加载文件或程序 ...

  10. [LeetCode] First Bad Version 第一个坏版本

    You are a product manager and currently leading a team to develop a new product. Unfortunately, the ...

随机推荐

  1. 使用 Linux 下的的logrotate进行日志的切割

    实际生产中,使用一个log文件来记录所有信息的话,一方面,时间过久,就会占用很大的空间:另一方面,就是一个文件记录对于后期日志的查看非常不利.为了解决查看了一下资料,发现linux里面有一个logro ...

  2. 使用GeoServer发布shp数据为WMS服务和WFS服务

    使用GeoServer发布shp数据为WMS服务和WFS服务 1安装GeoServer 2使用GeoServer上传数据 3使用GeoServer发布数据为WMS和WFS 看完本教程,你将学会安装Ge ...

  3. Web自动化selenium技术快速实现爬虫

    selenium是大家众所周知的web自动化测试框架,主要用来完成web网站项目的自动化测试,但其实如果要实现一个web爬虫,去某些网站爬取数据,其实用selenium来实现也很方便. 比如,我们现在 ...

  4. 用IDEA编写spark的WordCount

    我习惯用Maven项目 所以用IDEA新建一个Maven项目 下面是pom文件 我粘上来吧 <?xml version="1.0" encoding="UTF-8& ...

  5. lintcode 二分查找

    题目:二分查找 描述:给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1. c ...

  6. appium 元素定位与操作:

    一.常用识别元素的工具   uiautomator:Android SDK自带的一个工具,在tools目录下 monitor:Android SDK自带的一个工具,在tools目录下 Appium I ...

  7. Python基础 之 set集合 与 字符串格式化

    数据类型的回顾与总结 可变与不可变1.可变:列表,字典2.不可变:字符串,数字,元组 访问顺序:1.直接访问:数字2.顺序访问:字符串,列表,元祖3.映射:字典 存放元素个数:容器类型:列表,元祖,字 ...

  8. Laxcus大数据管理系统2.0(7)- 第五章 数据构建

    第五章 数据构建 在数据处理过程,我们经常会遇到这样的情况:大多数时候,用户最初输入的数据会含有大量无意义的.杂乱的信息,需要经过提炼.收集.汇总等一系列手段,才能产生有意义和用户可识别的数据内容:当 ...

  9. dotnetframe的清理工具

    微软的产品一向不敢恭维,卸载都没有办法卸载干净,卸载又慢又不彻底,dotnet被我卸载之后还有注册表残留以至于无法重新安装. .NET Framework Cleanup Tool真的很好用,全部版本 ...

  10. 【模板】DFS

    int dx[] = { 0,1,0,-1 }; int dy[] = { 1,0,-1,0 }; void dfs()//参数用来表示状态 { if (到达终点状态) { ...//根据题意来添加 ...