洛谷题目传送门

具体思路看别的题解吧。这里只提两个可能对常数和代码长度有优化的处理方法。

I

把一个询问拆成\(9\)个甚至\(16\)个莫队询问实在是有点珂怕。

发现询问的一边要么是一个区间,要么是\([1,n]\)挖去一个区间。

记\(pre_i=f_{[1,i],[1,n]}\),这个可以一遍预处理求出来。

简单容斥一下:

\[f_{[l,r],[1,L)\cup(R,n]}=f_{[l,r],[1,n]}-f_{[l,r],[L,R]}=pre_r-pre_{l-1}-f_{[l,r],[L,R]}
\]

\[f_{[1,l)\cup(r,n],[1,L)\cup(R,n]}=f_{[1,n],[1,n]}-f_{[l,r],[1,n]}-f_{[1,n],[L,R]}+f_{[l,r],[L,R]}=...
\]

于是对于每个询问,我们拆成\(4\)个莫队询问就够了,因为只差求\(f_{[l,r],[L,R]}\)。

II

如何求某一个点往新根方向上的儿子?树剖倍增什么的都太呆了。

预处理树的dfn序,每个点开一个map按dfn序挂上它所有的儿子,查询时拿着新根的dfn序直接lower_bound即可。

然后就可以2kb写完这道不算太毒瘤的由乃题了。

#include<bits/stdc++.h>
#define LL long long
#define RG register
#define R RG int
#define G if(++ip==ie)if(fread(ip=buf,1,SZ,stdin))
using namespace std;
const int SZ=1<<19,N=1e5+9,M=5e5+9;
char buf[SZ],*ie=buf+SZ,*ip=ie-1;
inline int in(){
G;while(*ip<'-')G;
R x=*ip&15;G;
while(*ip>'-'){x*=10;x+=*ip&15;G;}
return x;
}
struct Qry{
int x,y,b,id;
inline bool operator<(const Qry&t)const{
return b!=t.b?b<t.b:(1&b)?y>t.y:y<t.y;
}
}t[4*M];
int dfn,a[N],b[N],c1[N],c2[N],l[N],r[N],he[N],ne[2*N],to[2*N];
LL pre[N],ans[M];
map<int,int>ch[N];
void dfs(R x,R f){//预处理dfn序
l[x]=++dfn;
for(R y,i=he[x];i;i=ne[i])
if((y=to[i])!=f)dfs(y,x),ch[x][r[y]]=y;
r[x]=dfn;
}
int main(){
R n=in(),m=in(),q=0,B=sqrt(n);
for(R i=1;i<=n;++i)
a[i]=b[i]=in();
for(R i=1,p=0;i<n;++i){
R x=in(),y=in();
ne[++p]=he[x];to[he[x]=p]=y;
ne[++p]=he[y];to[he[y]=p]=x;
}
dfs(1,0);
sort(a+1,a+n+1);
for(R i=1;i<=n;++i)b[i]=lower_bound(a+1,a+n+1,b[i])-a;
for(R i=1;i<=n;++i)++c1[a[l[i]]=b[i]];//预处理pre
for(R i=1;i<=n;++i)pre[i]=pre[i-1]+c1[a[i]];
for(R i=1,rt=1;i<=m;++i){
if(in()&1){rt=in();--i;--m;continue;}
R x=in(),y=in();
R tx=l[x]<=l[rt]&&r[rt]<=r[x];if(x==rt)x=1,tx=0;
R ty=l[y]<=l[rt]&&r[rt]<=r[y];if(y==rt)y=1,ty=0;
if(tx)x=ch[x].lower_bound(l[rt])->second;//map找儿子
if(ty)y=ch[y].lower_bound(l[rt])->second;
R lx=l[x]-1,ly=l[y]-1,rx=r[x],ry=r[y];
if(tx&&ty)ans[i]=pre[n];
if(tx)ans[i]+=(pre[ry]-pre[ly])*(tx==ty?-1:1);
if(ty)ans[i]+=(pre[rx]-pre[lx])*(tx==ty?-1:1);
t[++q]=(Qry){rx,ry,rx/B,tx==ty?i:-i};//四个莫队询问,带上容斥系数
t[++q]=(Qry){rx,ly,rx/B,tx==ty?-i:i};
t[++q]=(Qry){lx,ry,lx/B,tx==ty?-i:i};
t[++q]=(Qry){lx,ly,lx/B,tx==ty?i:-i};
}
sort(t+1,t+q+1);
LL now=0;memset(c1+1,0,4*n);
for(R i=1,x=0,y=0;i<=q;++i){//莫队
while(x<t[i].x)++c1[a[++x]],now+=c2[a[x ]];
while(x>t[i].x)--c1[a[ x]],now-=c2[a[x--]];
while(y<t[i].y)++c2[a[++y]],now+=c1[a[y ]];
while(y>t[i].y)--c2[a[ y]],now-=c1[a[y--]];
R j=t[i].id;j>0?ans[j]+=now:ans[-j]-=now;
}
for(R i=1;i<=m;++i)
printf("%lld\n",ans[i]);
return 0;
}

洛谷P4689 [Ynoi2016]这是我自己的发明(莫队,树的dfn序,map,容斥原理)的更多相关文章

  1. 洛谷P4689 [Ynoi2016]这是我自己的发明 [莫队]

    传送门 ynoi中比较良心不卡常的题. 思路 没有换根操作时显然可以变成dfs序莫队随便搞. 换根操作时一个子树可以变成两段区间的并集,也随便搞搞就好了. 这题完全不卡常,随便过. 代码 #inclu ...

  2. 洛谷P4689 [Ynoi2016]这是我自己的发明(树上莫队+树链剖分)

    题目描述 您正在打galgame,然后突然家长进来了,于是您假装在写数据结构题: 给一个树,n 个点,有点权,初始根是 1. m 个操作,每次操作: 1.将树根换为 x. 2.给出两个点 x,y,从  ...

  3. 【洛谷】1972:[SDOI2009]HH的项链【莫队+树状数组】

    P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...

  4. 洛谷P4867 Gty的二逼妹子序列(莫队+树状数组)

    传送门 本来打算用主席树 然后发现没办法维护颜色数 于是用了莫队加树状数组 然后竟然A了…… //minamoto #include<iostream> #include<cstdi ...

  5. 【洛谷3674】小清新人渣的本愿(莫队,bitset)

    [洛谷3674]小清新人渣的本愿(莫队,bitset) 题面 洛谷,自己去看去,太长了 题解 很显然的莫队. 但是怎么查询那几个询问. 对于询问乘积,显然可以暴力枚举因数(反正加起来也是\(O(n\s ...

  6. 【洛谷5398】[Ynoi2018]GOSICK(二次离线莫队)

    题目: 洛谷 5398 当我刚学莫队的时候,他们告诉我莫队能解决几乎所有区间问题: 现在,当我发现一个区间问题似乎难以用我所了解的莫队解决的时候,他们就把这题的正解叫做 XXX 莫队.--题记 (以上 ...

  7. 洛谷P2709 BZOJ 3781 小B的询问 (莫队)

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...

  8. 【洛谷5072】[Ynoi2015] 盼君勿忘(莫队)

    点此看题面 大致题意: 一个序列,每次询问一个区间\([l,r]\)并给出一个模数\(p\),求模\(p\)意义下区间\([l,r]\)内所有子序列去重后值的和. 题意转化 原来的题意看起来似乎很棘手 ...

  9. 洛谷 P1494 [国家集训队]小Z的袜子(莫队)

    题目链接:https://www.luogu.com.cn/problem/P1494 一道很经典的莫队模板题,然而每道莫队题的大体轮廓都差不多. 首先莫队是一种基于分块的算法,它的显著特点就是: 能 ...

随机推荐

  1. 本地项目托管到github上

    一,步骤 1.在github上新建一个仓库 2.进入我的项目目录, git init //初始化本地仓库 3.git add . //把修改的代码提交到暂存区 4.git status 该命令会把你本 ...

  2. toTree

    // js实现树级递归, // 通过js生成tree树形菜单(递归算法) const data = [ { id: 1, name: "办公管理", pid: 0 }, { id: ...

  3. nodejs配置nginx 以后链接mongodb数据库

    服务器 :windows server2008 R2 反向代理 :nginx 1.15.1 for window 64位 数据库:mongodb 4 64位 使用框架express 首先下载nodej ...

  4. 使用docker化的nginx 反向代理 docker化的GSCloud 的方法

    1. 首先将nginx 的image pull 下来. docker pull nginx 2. 将最近的可用的 参数文件 复制过来当一个目录 mkdir /nginx ssh root@linuxs ...

  5. Ajax发送请求等待时弹出模态框等待提示

    主要的代码分为两块,一个是CSS定义模态框,另一个是在Ajax中弹出模态框. 查看菜鸟教程中的模态框教程demo,http://www.runoob.com/try/try.php?filename= ...

  6. Notepad++ 安装 NppFTP 插件

    How to install a plugin The plugin (in the DLL form) should be placed in the \plugins subfolder of t ...

  7. scala mkstring

    如果你想要把集合元素转化为字符串,可能还会添加分隔符,前缀,后缀. Solution 使用mkString方法来打印一个集合内容,下面给一个简单的例子: scala> val a = Array ...

  8. python之路--BOM和DOM

    一. 介绍 之前学的JS的一些简单的语法并没有和浏览器有任何的交互. 我们要想制作一些我们经常看到的网页的一些交互,我们需要继续学习BOM和DOM相关知识. JavaScript 分为 ECMAScr ...

  9. Partition算法以及其应用详解下(Golang实现)

    接前文,除了广泛使用在快速排序中.Partition算法还可以很容易的实现在无序序列中使用O(n)的时间复杂度查找kth(第k大(小)的数). 同样根据二分的思想,每完成一次Partition我们可以 ...

  10. python学习笔记(3)--turtle简单绘制

    参考:大学生mooc 北京理工大学的python程序与设计课程 蟒蛇绘制代码如下: #pythonDraw.py import turtle turtle.setup(650,350,200,200) ...