洛谷题目传送门

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

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. python中变量、函数、类名、模块名等命名方式

    摘要:模块名:小写字母,单词之间用_分割ad_stats.py包名:和模块名一样类名:单词首字母大写AdStatsConfigUtil全局变量名(类变量,在java中相当于static变量):大写字母 ...

  2. web安全测试排查

    漏洞排查思路: 1.上传漏洞 如果看到:选择你要上传的文件 [重新上传]或者出现“请登陆后使用”,80%就有漏洞了! 有时上传不一定会成功,这是因为Cookies不一样.我们就要用WSockExper ...

  3. springboot 整合spark-sql报错

    Exception in thread "main" org.spark_project.guava.util.concurrent.ExecutionError: java.la ...

  4. HTTL之初印象

    概述 HTTL (Hyper-Text Template Language) 是一个高性能的开源JAVA模板引擎, 适用于动态HTML页面输出, 可替代JSP页面, 指令和Velocity相似. 简洁 ...

  5. [转帖]Stack的三种含义

    Stack的三种含义 http://www.ruanyifeng.com/blog/2013/11/stack.html 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈&q ...

  6. 关于标准的知识 GB ISO 等内容

    1. 来自百度知道: GB:GB 即"国标"的汉语拼音缩写,为中华人民共和国国家标准的意思. ISO:国际标准化组织的英语简称.其全称是International Organiza ...

  7. SQLSERVER sa 用户密码修改的方法

    本次驱动人生病毒的收获 . 偷懒总会有报应. . 应用(数据库或者是web应用nginx等.)都不要使用最高级别权限用户来使用 虽然这样的环境问题最少. . 密码还是需要定期更换的,虽然有成本,但是也 ...

  8. 在linux上安装Scala详细步骤

    scala在linux安装很简单,就是下载,解压,配置环境变量,source一下成功. 提君博客原创 >>提君博客原创 http://www.cnblogs.com/tijun/ < ...

  9. (一)类数组对象NodeList

    NodeList对象的特点: NodeList是一种类数组对象,用于保存一组有序的节点. 可以通过方括号语法来访问NodeList的值,有item方法与length属性. 它并不是Array的实例,没 ...

  10. 剑指offer(4)

    题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2 ...