看到这个标题立刻想到:、

“绝地科学家,八倍不屏息啊,八百里外把头打啊...”

首先我们发现如果只考虑第二个操作,这棵树就是假的,我们可以直接莫队解决

如果考虑换根的话...可以把一个操作换成小于等于9个操作就可以了

当然怎么换,有一些非常恶心的分类讨论

嘤嘤嘤

YNOI 题是好题 但是要卡常 首先要fread & fwrite

然后需要wxh的莫队写法

然后要算一下分块大小

sqrt(q_size) -> (n / sqrt(q_size))

40 -> 100

嘤嘤嘤

#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline char nc()
{
static char buf[] , *p1 , *p2;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf , , , stdin) , p1 == p2) ? EOF : *p1 ++ ;
}
inline int read()
{
int ret = ; char ch = nc();
while(!isdigit(ch)) ch = nc();
while(isdigit(ch)) ret = ((ret + (ret << )) << ) + (ch ^ '') , ch = nc();
return ret;
}
char pbuf[] , *pp = pbuf;
inline void push(const char ch)
{
if(pp == pbuf + ) fwrite(pbuf , , , stdout) , pp = pbuf;
*pp ++ = ch;
}
inline void write(long long x)
{
static char sta[];
int top = ;
if(!x) push('');
while(x) sta[++top] = x % ^ '' , x /= ;
while(top) push(sta[top -- ]);
push('\n');
}
const int maxn = ;
int n,m,rt;
int qx;
int a[maxn],vi[maxn];
int q_size;
int first[maxn],to[maxn << ],nx[maxn << ],cnt;
inline void add(int u,int v)
{
to[++cnt] = v;
nx[cnt] = first[u];
first[u] = cnt;
}
inline void ins(int u,int v){add(u,v);add(v,u);}
struct Q
{
int l,r,bl,id,opt;
Q(){};
Q(int _l,int _r,int _id,int _opt){l = min(_l,_r),r = max(_l,_r),id = _id,opt = _opt;}
bool operator < (const Q &b)const
{
if(bl == b.bl)
{
if(bl & )
return r < b.r;
return r > b.r;
}
return l < b.l;
}
}qs[maxn * ];
int fa[maxn][],dep[maxn],ind[maxn],oud[maxn],reh[maxn],dfn;
inline void dfs(int x)
{
ind[x] = ++dfn;reh[dfn] = a[x];
for(int i=;i<=;i++)
fa[x][i] = fa[fa[x][i - ]][i - ];
for(int i=first[x];i;i=nx[i])
{
if(to[i] == fa[x][])continue;
dep[to[i]] = dep[x] + ;
fa[to[i]][] = x;
dfs(to[i]);
}oud[x] = dfn;
}
LL ans[maxn * ];
LL now;int cnt_x[maxn],cnt_y[maxn];
inline int go_anc(int x , int y)
{
int i;
for(i = ; ~i ; i -- )
if(dep[y] - dep[x] > ( << i))
y = fa[y][i];
return y;
}
int xpos[],ypos[],opt_x[],opt_y[];
int main()
{
freopen("1.in","r",stdin);
freopen("www.out","w",stdout);
int tx,ty;
n = read(),m = read();
for(int i=;i<=n;i++)vi[i] = a[i] = read();
sort(vi + ,vi + n + );
for(int i=;i<=n;i++)a[i] = lower_bound(vi + ,vi + n + ,a[i]) - vi;
for(int i=;i<=n;i++)
{
int u = read(),v = read();
ins(u,v);
}dfs(rt = );
//return 0;
for(int i=;i<=m;i++)
{
int t = read(),x = read();
if(t == ){rt = x;continue;}
int y = read(),z;q_size++;
tx = ty = ;
if(x == rt) xpos[++tx] = n , opt_x[tx] = ;
else if(ind[rt] < ind[x] || ind[rt] > oud[x]) xpos[++tx] = oud[x] , opt_x[tx] = , xpos[++tx] = ind[x] - , opt_x[tx] = -;
else z = go_anc(x , rt) , xpos[++tx] = n , opt_x[tx] = , xpos[++tx] = oud[z] , opt_x[tx] = - , xpos[++tx] = ind[z] - , opt_x[tx] = ; if(y == rt) ypos[++ty] = n , opt_y[ty] = ;
else if(ind[rt] < ind[y] || ind[rt] > oud[y]) ypos[++ty] = oud[y] , opt_y[ty] = , ypos[++ty] = ind[y] - , opt_y[ty] = -;
else z = go_anc(y , rt) , ypos[++ty] = n , opt_y[ty] = , ypos[++ty] = oud[z] , opt_y[ty] = - , ypos[++ty] = ind[z] - , opt_y[ty] = ; for(int j=;j<=tx;j++)
for(int k=;k<=ty;k++)
if(xpos[j] && ypos[k])
qs[++qx] = Q(xpos[j] , ypos[k] , q_size , opt_x[j] * opt_y[k]);
}
int si = (int)(n / sqrt(qx));
for(int i=;i<=qx;i++)qs[i].bl = (qs[i].l - ) / si;
sort(qs + ,qs + qx + );
int l = ,r = ;
for(int i=;i<=qx;i++)
{
while(l < qs[i].l){l++;now += cnt_y[reh[l]],cnt_x[reh[l]]++;}
while(r < qs[i].r){r++;now += cnt_x[reh[r]],cnt_y[reh[r]]++;}
while(l > qs[i].l){cnt_x[reh[l]]--;now -= cnt_y[reh[l]];l--;}
while(r > qs[i].r){cnt_y[reh[r]]--;now -= cnt_x[reh[r]];r--;}
ans[qs[i].id] += now * qs[i].opt;
}
for(int i=;i<=q_size;i++)write(ans[i]);
fwrite(pbuf , , pp - pbuf , stdout);
}

YNOI2016 这是我自己的发明的更多相关文章

  1. 洛谷P4689 [Ynoi2016]这是我自己的发明(莫队,树的dfn序,map,容斥原理)

    洛谷题目传送门 具体思路看别的题解吧.这里只提两个可能对常数和代码长度有优化的处理方法. I 把一个询问拆成\(9\)个甚至\(16\)个莫队询问实在是有点珂怕. 发现询问的一边要么是一个区间,要么是 ...

  2. [Ynoi2016]这是我自己的发明 莫队

    传送门:here 很棒的莫队题啊..... 题意: 有一棵$ n$个点的树,树上每个点有点权,有$ m$次询问: 操作1:给定两个点$ x,y$,求二元组$ (a,b)$的数量,要求$ a$在$ x$ ...

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

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

  4. bzoj4940: [Ynoi2016]这是我自己的发明

    用dfs序把询问表示成询问dfs序的两个区间中的信息 拆成至多9个询问(询问dfs序的两个前缀),对这些询问用莫队处理,时间复杂度$O(n\sqrt{m})$ #include<bits/std ...

  5. [Ynoi2016]这是我自己的发明(莫队)

    话说这道题数据是不是都是链啊,我不手动扩栈就全 \(RE\)... 不过 \(A\) 了这题还是很爽的,通过昨晚到今天早上的奋斗,终于肝出了这题 其实楼上说的也差不多了,就是把区间拆掉然后莫队瞎搞 弱 ...

  6. 【bzoj4940】[Ynoi2016]这是我自己的发明 DFS序+树上倍增+莫队算法

    题目描述 给一个树,n 个点,有点权,初始根是 1. m 个操作,每次操作: 1. 将树根换为 x. 2. 给出两个点 x,y,从 x 的子树中选每一个点,y 的子树中选每一个点,如果两个点点权相等, ...

  7. Luogu4689 [Ynoi2016]这是我自己的发明 【莫队】

    题目链接:洛谷 又来做Ynoi里面的水题了... 首先换根的话是一个套路,首先以1为根dfs,然后画一画就知道以rt为根,x的子树是什么了.可以拆分为2个dfs连续段. 然后如果要计算\([l_1,r ...

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

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

  9. bzoj4940 [Ynoi2016]这是我自己的发明 莫队+dfs序

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4940 题解 对于换根操作,处理方法就很套路了. 首先先假定以 \(1\) 为根做一遍 dfs, ...

随机推荐

  1. pycharm中不能安装bs4的解决方案

    首先:什么Beautiful Soup? Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.B ...

  2. python高级-------python2.7教程学习【廖雪峰版】(四)

    2017年6月9日17:57:55 任务: 看完高级部分 笔记:1.掌握了Python的数据类型.语句和函数,基本上就可以编写出很多有用的程序了.2.在Python中,代码不是越多越好,而是越少越好. ...

  3. Nodejs通过thrift访问Java服务

    上一篇文章中实现了用Java作为thrift客户端和服务端.接下来我们用nodejs作为客户端访问一下.Nodejs的安装可以查看http://www.cnblogs.com/xucheng/p/39 ...

  4. Python 推导式、迭代器、生成器、模块和包

    一.推导式 (一).列表推导式(集合推导式也同理于此) 利用列表推导式,取出1-20内所有偶数 li = [i for i in range(1, 21) if i % 2 == 0] # 如果只有一 ...

  5. Netty实现java多线程Post请求解析(Map参数类型)—SKY

    netty解析Post的键值对 解析时必须加上一个方法,ch.pipeline().addLast(new HttpObjectAggregator(2048)); 放在自己的Handel前面. ht ...

  6. eclipse里面用svn关联项目

    eclipse里面共享项目经常会用到svn或者git插件 关联项目的步骤如下: 如果 点击finish会遇到卡住问题的话,不要着急,我们需要设置svn的client设置: 如果设置了之后还是很卡的话, ...

  7. intellij idea 自动生成setter getter

    windows下: alt + insert,然后选择要生成的成员. mac下: command + N

  8. [note]CRT&exCRT

    中国剩余定理 别人的blog 假设现在有关于x的同余方程组(p1,p2均为质数) \(x=a_1\pmod {p_1}\) \(x=a_2\pmod {p_2}\) 可以转化成如下形式 \(x=a_1 ...

  9. JPA hibernate spring repository pgsql java 工程(二):sql文件导入数据,测试数据

    使用jpa保存查询数据都很方便,除了在代码中加入数据外,可以使用sql进行导入.目前我只会一种方法,把数据集中在一个sql文件中. 而且数据在导入中常常具有先后关系,需要用串行的方式导入. 第一步:配 ...

  10. CentOS iSCSI服务器搭建------Target篇

    先上服务器信息(当然是我YY的服务器.哈哈) [root@node ~]# cat /etc/redhat-release CentOS release 6.6 (Final) [root@node ...