洛谷P4689 [Ynoi2016]这是我自己的发明(莫队,树的dfn序,map,容斥原理)
具体思路看别的题解吧。这里只提两个可能对常数和代码长度有优化的处理方法。
I
把一个询问拆成\(9\)个甚至\(16\)个莫队询问实在是有点珂怕。
发现询问的一边要么是一个区间,要么是\([1,n]\)挖去一个区间。
记\(pre_i=f_{[1,i],[1,n]}\),这个可以一遍预处理求出来。
简单容斥一下:
\]
\]
于是对于每个询问,我们拆成\(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,容斥原理)的更多相关文章
- 洛谷P4689 [Ynoi2016]这是我自己的发明 [莫队]
传送门 ynoi中比较良心不卡常的题. 思路 没有换根操作时显然可以变成dfs序莫队随便搞. 换根操作时一个子树可以变成两段区间的并集,也随便搞搞就好了. 这题完全不卡常,随便过. 代码 #inclu ...
- 洛谷P4689 [Ynoi2016]这是我自己的发明(树上莫队+树链剖分)
题目描述 您正在打galgame,然后突然家长进来了,于是您假装在写数据结构题: 给一个树,n 个点,有点权,初始根是 1. m 个操作,每次操作: 1.将树根换为 x. 2.给出两个点 x,y,从 ...
- 【洛谷】1972:[SDOI2009]HH的项链【莫队+树状数组】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- 洛谷P4867 Gty的二逼妹子序列(莫队+树状数组)
传送门 本来打算用主席树 然后发现没办法维护颜色数 于是用了莫队加树状数组 然后竟然A了…… //minamoto #include<iostream> #include<cstdi ...
- 【洛谷3674】小清新人渣的本愿(莫队,bitset)
[洛谷3674]小清新人渣的本愿(莫队,bitset) 题面 洛谷,自己去看去,太长了 题解 很显然的莫队. 但是怎么查询那几个询问. 对于询问乘积,显然可以暴力枚举因数(反正加起来也是\(O(n\s ...
- 【洛谷5398】[Ynoi2018]GOSICK(二次离线莫队)
题目: 洛谷 5398 当我刚学莫队的时候,他们告诉我莫队能解决几乎所有区间问题: 现在,当我发现一个区间问题似乎难以用我所了解的莫队解决的时候,他们就把这题的正解叫做 XXX 莫队.--题记 (以上 ...
- 洛谷P2709 BZOJ 3781 小B的询问 (莫队)
题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...
- 【洛谷5072】[Ynoi2015] 盼君勿忘(莫队)
点此看题面 大致题意: 一个序列,每次询问一个区间\([l,r]\)并给出一个模数\(p\),求模\(p\)意义下区间\([l,r]\)内所有子序列去重后值的和. 题意转化 原来的题意看起来似乎很棘手 ...
- 洛谷 P1494 [国家集训队]小Z的袜子(莫队)
题目链接:https://www.luogu.com.cn/problem/P1494 一道很经典的莫队模板题,然而每道莫队题的大体轮廓都差不多. 首先莫队是一种基于分块的算法,它的显著特点就是: 能 ...
随机推荐
- 关于always块内for循环的执行方式
//该模块主要用来说明for结构在时序逻辑中的执行方式 :] eq_dly ); integer i; 'b1; always @(posedge clk_1 or negedge nrst) beg ...
- MyBatis模糊查询不报错但查不出数据的一种解决方案
今天在用MyBatis写一个模糊查询的时候,程序没有报错,但查不出来数据,随即做了一个测试,部分代码如下: @Test public void findByNameTest() throws IOEx ...
- git [command line] fatal: Authentication failed for
fatal: Authentication failed for https://www.jianshu.com/p/8a7f257e07b8 git.exe fetch -v --progress ...
- [翻译]在asp.net core2.0 OpenID Connect Handler中丢失了声明(CLaims)?
注:这是一篇翻译,来自这里.这篇文章讲述了在asp.net core2.0中使用openid connect handler的过程中解析不到你想要的claim时,你可以参考这篇文章. Missing ...
- oracle一些单记录函数
单记录函数 1.0 NVL() 作用:从两个表达式返回一个非NULL值 用法:NVL(表达式1, 表达式2) 如果表达式1的结果不为NULL,返回表达式1的结果:如果表达式1的结果为NULL,返回表达 ...
- 120. 单词接龙 (BFS)
描述 给出两个单词(start和end)和一个字典,找到从start到end的最短转换序列 比如: 每次只能改变一个字母. 变换过程中的中间单词必须在字典中出现. 如果没有转换序列则返回0. 所有单词 ...
- (C/C++)区别:数组与指针,指针与引用
1.数组跟指针的区别 数组要么在静态存储区被创建(如全局数组),要么在栈上被创建.数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变. 指针可以随时指向任意类型 ...
- Leetcode SingleNumber I & II & III 136/137/260
SingleNumber I: 题目链接:https://leetcode-cn.com/problems/single-number/ 题意: 给定一个非空整数数组,除了某个元素只出现一次以外,其余 ...
- hive JDBC客户端启动
JDBC客户端操作步骤
- C# json解析
json格式数 [{ , , , "ItemCode": "UBAC11211OF-A54", "basicName_bg": " ...