【牛客挑战赛32E】树上逆序对
数据范围非常奇怪,询问的逆序对个数\(k\leq 30000\),我们应该可以把所有的情况都求出来
发现对于树上两点\(x,y\),如果\(x\)是\(y\)的祖先,那么绝对值较大的点的符号决定了能否形成逆序对
如果\(a_x>a_y\),不取反\(a_x\),那么无论\(a_y\)取反与否,肯定会形成逆序对,因为\(a_x>a_y>-a_y\);反之如果取反\(a_x\),那么无论\(a_y\)取反与否,肯定不对形成逆序对,因为\(a_y>-a_y>-a_x\)
于是我们按照绝对值从小到大排序,之后按照顺序加入树中,一个点对答案的贡献是其子树内部小于它的点的个数加上到根的路径上大于它的点的个数;当我们加入一个点\(x\)时,如果不取反,那么到根的路径上显然不会有点大于它,且子树内部全都小于它,形成的逆序对个数就是其子树内部的点的个数;如果取反,那么到根的路径上的点全都大于它,子树内部不会有点小于它,形成的逆序对个数就是到根的路径上点的个数
所以用树剖+树状数组求一下,之后搞一个背包来转移就好了,背包需要\(\rm bitset\)优化
复杂度\(O(n\log^2n+\frac{nk}{w})\)
代码
#include<bits/stdc++.h>
#define re register
#define LL long long
#define lb(i) (i&-i)
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=1e5+5;
struct E{int v,nxt;}e[maxn<<1];
struct pt{int x,id;}a[maxn];
std::bitset<300001> dp;
int n,num,Q,c[maxn],__;
int sum[maxn],dfn[maxn],top[maxn],fa[maxn],head[maxn],deep[maxn],son[maxn];
inline int cmp(pt A,pt B) {return A.x<B.x;}
inline void add(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
inline void ins(int x) {
for(re int i=x;i<=n;i+=lb(i)) c[i]++;
}
inline int ask(int x) {
int now=0;
for(re int i=x;i;i-=lb(i)) now+=c[i];
return now;
}
inline int calc(int l,int r) {return ask(r)-ask(l-1);}
inline int get(int x) {
int now=0;
while(top[x]) now+=calc(dfn[top[x]],dfn[x]),x=fa[top[x]];
return now;
}
void dfs1(int x) {
sum[x]=1;
for(re int i=head[x];i;i=e[i].nxt) {
if(deep[e[i].v]) continue;
deep[e[i].v]=deep[x]+1,fa[e[i].v]=x;
dfs1(e[i].v),sum[x]+=sum[e[i].v];
if(sum[e[i].v]>sum[son[x]]) son[x]=e[i].v;
}
}
void dfs2(int x,int topf) {
top[x]=topf,dfn[x]=++__;
if(!son[x]) return;
dfs2(son[x],topf);
for(re int i=head[x];i;i=e[i].nxt)
if(!top[e[i].v]) dfs2(e[i].v,e[i].v);
}
int main() {
n=read();
for(re int i=1;i<=n;i++) a[i].x=read(),a[i].id=i;
for(re int x,y,i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
deep[1]=1,dfs1(1),dfs2(1,1);
std::sort(a+1,a+n+1,cmp);
dp[0]=1;
for(re int i=1;i<=n;i++) {
int x=calc(dfn[a[i].id],dfn[a[i].id]+sum[a[i].id]-1),y=get(a[i].id);
dp=(dp<<x)|(dp<<y);ins(dfn[a[i].id]);
}
Q=read();while(Q--) puts(dp[read()]?"Orz":"QAQ");
return 0;
}
【牛客挑战赛32E】树上逆序对的更多相关文章
- 牛客挑战赛32E 树上逆序对
nowcoder 口胡一时爽 先从这个逆序对的性质入手,手玩可以发现对于一对具有祖先关系节点的点,只有权值绝对值大的才能对这一对点是否为逆序对造成影响.具体来讲,如果祖先点权值大,并且取正号,那么其后 ...
- 牛客挑战赛32 E. 树上逆序对
对于一对 $(x, y)$,能成为逆序对的取决于绝对值大的那个数的符号.假如 $a[x] > a[y]$,当 $a[x]$ 为正时,不管 $a[y]$ 取不取负号都比 $a[x]$ 小.当 $a ...
- 牛客挑战赛 39 牛牛与序列 隔板法 容斥 dp
LINK:牛牛与序列 (牛客div1的E题怎么这么水... 还没D难. 定义一个序列合法 当且仅当存在一个位置i满足 $a_i>a_,a_j<a_$且对于所有的位置i,$1 \leq a_ ...
- 牛客挑战赛46 C
题目链接: 排列 考虑\(dp\),我们思考如何设计状态 将第i个数插入i-1个数中,我们考虑会新增多少个超级逆序对 假设将\(i\)插入后\(i\)的位置为\(l\),\(i-1\)的原来的位置为\ ...
- 牛客挑战赛33 F 淳平的形态形成场(无向图计数,EGF,多项式求逆)
传送门: 淳平的形态形成场 题解: 把a排序后,直接统计答案恰好为a[i]并不好做,可以统计答案>a[i]的方案数,设为\(f[i]\). 即不存在一个联通块,所有的权值都<=a[i]. ...
- 良心送分题(牛客挑战赛35E+虚树+最短路)
目录 题目链接 题意 思路 代码 题目链接 传送门 题意 给你一棵树,然后把这棵树复制\(k\)次,然后再添加\(m\)条边,然后给你起点和终点,问你起点到终点的最短路. 思路 由于将树复制\(k\) ...
- 牛客挑战赛 30 A 小G数数
题目链接:https://ac.nowcoder.com/acm/contest/375/A 分析:我写的时候竟然把它当成了DP....... 还建了个结构体DP数组,保存一二位,不知道当时脑子在抽啥 ...
- 牛客挑战赛14-F细胞
https://www.nowcoder.com/acm/contest/81/F 循环卷积的裸题,太久没做FFT了,这么裸的循环卷积都看不出来 注意一下本文的mod 都是指表示幂的模数,而不是NTT ...
- Luogu5611 Ynoi2013 D2T2/牛客挑战赛32F 最大子段和 分块、分治
传送门 之前一直咕着的,因为一些特殊的原因把这道题更掉算了-- 有一个对值域莫队+线段树的做法,复杂度\(O(n\sqrt{n} \log n)\)然而牛客机子实在太慢了没有希望(Luogu上精细实现 ...
随机推荐
- jquery中的ajax方法参数的用法和他的含义
jquery中的ajax方法参数的用法和他的含义: 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(pos ...
- 广度优先搜索(Breadth First Search)
Date:2019-07-03 14:29:02 走完一层的所有房间,再走下一层,用队列实现 算法实现 /*--------------------------模版------------------ ...
- 面向对象(三)——组合、多态、封装、property装饰器
组合.多态.封装.property装饰器 一.组合 1.什么是组合 组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象 class Foo(): pass class Bar(): pas ...
- 网络编程(四)——基于udp协议的套接字socket、socketserver模块的使用
基于udp协议的套接字.socketserver模块 一.UDP协议(数据报协议) 1.何为udp协议 不可靠传输,”报头”部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包. ...
- leetcode.字符串.242有效的字母异位词-Java
1. 具体题目 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 注:判断两个字符串包含的字母是否完全一样. 示例 1: 输入: s = "anagram&q ...
- mysql全套
1. 什么是数据库 存储数据的仓库 2. 什么数据: 大家所知道的都是数据.比如:你同学的名字,年龄,性别等等 3. 数据库概念 1.数据库服务器 2.数据库管理系统 重点 3.库 4.表 5.记录 ...
- Vue之获取用户当前所在省市
今天小编给大家带来的是使用Vue获取用户所在城市,Vue是很强大的,给大家准备好现成的插件供大家调用,下面的Demo小编使用的是百度API. 首先我们从百度平台申请百度地图的秘钥,申请成功后我们将&l ...
- 小白如何在Windows下使用Redis
一.redis下载按装 Nuget 可以直接下载 redis 将下来的包拷贝到自已需要的目录如我放到桌面文件夹“近期需要\Redis应用\redis-64.3.0.503” 操作 cmd进入命令操作 ...
- tzfile - 时区信息
SYNOPSIS #include <tzfile.h> DESCRIPTION 时区信息文件被 tzset(3) 使用, 其开头为特征字符"TZif", 以此标示该文 ...
- 小波变换C代码
#include <stdio.h> #include <stdlib.h> #define LENGTH 512//信号长度 /*********************** ...