YNOI2016 这是我自己的发明
看到这个标题立刻想到:、
“绝地科学家,八倍不屏息啊,八百里外把头打啊...”
首先我们发现如果只考虑第二个操作,这棵树就是假的,我们可以直接莫队解决
如果考虑换根的话...可以把一个操作换成小于等于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 这是我自己的发明的更多相关文章
- 洛谷P4689 [Ynoi2016]这是我自己的发明(莫队,树的dfn序,map,容斥原理)
洛谷题目传送门 具体思路看别的题解吧.这里只提两个可能对常数和代码长度有优化的处理方法. I 把一个询问拆成\(9\)个甚至\(16\)个莫队询问实在是有点珂怕. 发现询问的一边要么是一个区间,要么是 ...
- [Ynoi2016]这是我自己的发明 莫队
传送门:here 很棒的莫队题啊..... 题意: 有一棵$ n$个点的树,树上每个点有点权,有$ m$次询问: 操作1:给定两个点$ x,y$,求二元组$ (a,b)$的数量,要求$ a$在$ x$ ...
- 洛谷P4689 [Ynoi2016]这是我自己的发明 [莫队]
传送门 ynoi中比较良心不卡常的题. 思路 没有换根操作时显然可以变成dfs序莫队随便搞. 换根操作时一个子树可以变成两段区间的并集,也随便搞搞就好了. 这题完全不卡常,随便过. 代码 #inclu ...
- bzoj4940: [Ynoi2016]这是我自己的发明
用dfs序把询问表示成询问dfs序的两个区间中的信息 拆成至多9个询问(询问dfs序的两个前缀),对这些询问用莫队处理,时间复杂度$O(n\sqrt{m})$ #include<bits/std ...
- [Ynoi2016]这是我自己的发明(莫队)
话说这道题数据是不是都是链啊,我不手动扩栈就全 \(RE\)... 不过 \(A\) 了这题还是很爽的,通过昨晚到今天早上的奋斗,终于肝出了这题 其实楼上说的也差不多了,就是把区间拆掉然后莫队瞎搞 弱 ...
- 【bzoj4940】[Ynoi2016]这是我自己的发明 DFS序+树上倍增+莫队算法
题目描述 给一个树,n 个点,有点权,初始根是 1. m 个操作,每次操作: 1. 将树根换为 x. 2. 给出两个点 x,y,从 x 的子树中选每一个点,y 的子树中选每一个点,如果两个点点权相等, ...
- Luogu4689 [Ynoi2016]这是我自己的发明 【莫队】
题目链接:洛谷 又来做Ynoi里面的水题了... 首先换根的话是一个套路,首先以1为根dfs,然后画一画就知道以rt为根,x的子树是什么了.可以拆分为2个dfs连续段. 然后如果要计算\([l_1,r ...
- 洛谷P4689 [Ynoi2016]这是我自己的发明(树上莫队+树链剖分)
题目描述 您正在打galgame,然后突然家长进来了,于是您假装在写数据结构题: 给一个树,n 个点,有点权,初始根是 1. m 个操作,每次操作: 1.将树根换为 x. 2.给出两个点 x,y,从 ...
- bzoj4940 [Ynoi2016]这是我自己的发明 莫队+dfs序
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4940 题解 对于换根操作,处理方法就很套路了. 首先先假定以 \(1\) 为根做一遍 dfs, ...
随机推荐
- vue2+element组件库开发
Vue2:https://cn.vuejs.org/v2/guide/single-file-components.html element组件库:http://element-cn.eleme.io ...
- 初识Modbus TCP/IP-------------C#编写Modbus TCP客户端程序(一)
转自:http://blog.csdn.net/thebestleo/article/details/52269999 首先我要说明一下,本人新手一枚,本文仅为同样热爱学习的同学提供参考,有不 对的地 ...
- 阿里云+LAMP环境配置
1. 准备好一键Linux环境的脚本: http://dwz.cn/6Nlexm 2. 运行命令:# yum install lynx tree nmap sysstat lrzsz dos2unix ...
- 我的设计模式学习笔记------>单例模式(Singleton)
一.前言 有些时候,允许自由创建某个类的实例是没有意义,还可能造成系统性能下降(因为创建对象所带来的系统开销问题).例如整个Windows系统只有一个窗口管理器,只有一个回收站等.在Java EE应用 ...
- linux c编程:信号(一)
信号是软件中断,很多比较重要的应用程序都需要处理信号.并且信号提供了一种处理异步事件的方法.如终端用户键入中断键,会通过信号机制停止一个程序,或及早终止管道中的下一个程序 很多条件都可以产生信号,比如 ...
- Symfony 没有找到数据库驱动An exception occured in driver: could not find driver
如果一直报这个错误, 第一,你本地没有相关的数据库驱动(mysql:-->pdo_myql,postgresql-->pdo_pgsql等); 需要执行 php -m|grep -i pd ...
- 如何从统计中批量获取BD搜索关键词及对应的入口页面?
前面我们介绍了通过cnzz的访问明细获取到搜索关键词及对应的入口页面,但是从BD搜索进来的关键词无法完整显示,只能呈现一些bd图片搜索的关键词,这是因为百度宣布从去年5月开始逐渐取消了referer关 ...
- codeforces Gravity Flip 题解
版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/,未经本作者同意不得转载. https://blog.csdn.net/kenden23/article ...
- js与jquey的表达
jquery 1.$("#id").css("display") 2.$(this) 3.attr(a,b) :在a里面追加元素b 4.prop: functi ...
- Java中的String,StringBuilder,StringBuffer三者的区别(转发:https://www.cnblogs.com/su-feng/p/6659064.html)
最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...