wannafly 练习赛11 F 求子树(树上莫队+换根)
链接:https://www.nowcoder.com/acm/contest/59/F
时间限制:C/C++ 1秒,其他语言2秒
64bit IO Format: %lld
题目描述
给一个n个点的树,第i个点的值是vi,初始根是1。
有m个操作,每次操作:
1.将树根换为x。
2.给出两个点x,y,求所有点对(a,b)的个数满足a在x子树中,b在y子树中,va==vb
输入描述:
第一行两个数表示n,m
第二行n个数,表示每个点的点权vi
之后n-1行,每行两个数x,y表示一条边
之后m行,每行为:
1 x表示把根换成x点
2 x y表示查询x点的子树与y点的子树
输出描述:
对于每个询问,输出一行一个数表示答案
输入例子:
5 5
1 2 3 4 5
1 2
1 3
3 4
3 5
2 4 5
2 1 5
2 3 5
1 5
2 4 5
输出例子:
0
1
1
1
-->
输入
5 5
1 2 3 4 5
1 2
1 3
3 4
3 5
2 4 5
2 1 5
2 3 5
1 5
2 4 5
输出
0
1
1
1
备注:
对于100%的数据,1 <= n <= 1e5 , 1<= m <= 5e5 , 1 <= vi<= 1e9
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
不是很懂,,一直超时,可能被卡常数了,,但是不想再码了,很绝望,不辜负自己码并且调那么久,还是把自己的超时代码发上来
#include<cstdio>
#include<algorithm>
#define mst(a,b) memset((a),(b), sizeof a)
#define lowbit(a) ((a)&(-a))
#define IOS ios::sync_with_stdio(0);cin.tie(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int mod=1e9+;
const int maxn=1e5+;
const int maxm=8e6;
int n,m;
int val[maxn],mx;
pii use[maxn];
void init_val(){
for(int i=;i<=n;++i)use[i].first=val[i],use[i].second=i;
sort(use+,use++n);
int cc=;
val[use[].second]=;
for(int i=;i<=n;++i){
if(use[i].first==use[i-].first)val[use[i].second]=cc-;
else val[use[i].second]=cc++;
}
}
vector<int>to[maxn];
int dfsn[maxn],cnt; pii mine[maxn][];int v[maxn]; inline void dfs(int pos,int fa){
int le,ri;
dfsn[++cnt]=pos;
le=cnt;
for(int i=;i<to[pos].size();++i)if(to[pos][i]!=fa)dfs(to[pos][i],pos);
ri=cnt;
mine[pos][] = make_pair(le,ri);
} struct node{
int id,a,b;
node(int _id,int _a,int _b){id=_id,a=_a,b=_b;}
};
vector<node>w[maxn];
ll ans[maxn<<],cc;
struct query{
int foo,l,r,bel;bool ti;
query(int a=,bool b=,int c=,int d=):foo(a),ti(b),l(c),r(d){};
};
query all[maxm];int sz; inline void add_q(int l1,int r1,int l2,int r2,int foo){
if(r1&&r2) all[++sz]=query(foo,true,min(r1,r2),max(r1,r2));
if(l1-&&r2) all[++sz]=query(foo,false,min(l1-,r2),max(l1-,r2));
if(l2-&&r1) all[++sz]=query(foo,false,min(l2-,r1),max(l2-,r1));
if(l1-&&l2-) all[++sz]=query(foo,true,min(l1-,l2-),max(l1-,l2-));
} inline void add_query(int a,int b,int foo){
for(int i=;i<v[a];++i)for(int j=;j<v[b];++j)
add_q(mine[a][i].first,mine[a][i].second,mine[b][j].first,mine[b][j].second,foo);
}
inline void change(int from,int to){
v[from]=;
if(v[to]==){
mine[from][v[from]++] = make_pair(mine[to][].second+,mine[to][].first-);
}else{
if(mine[to][].first!=)
mine[from][v[from]++] = make_pair(,mine[to][].first-);
if(mine[to][].second!=n)
mine[from][v[from]++] = make_pair(mine[to][].second+,n); }
v[to]=;
mine[to][] = make_pair(,n);
}
inline void getq(int pos,int fa){
for(int i=;i<w[pos].size();++i)
add_query(w[pos][i].a , w[pos][i].b , w[pos][i].id); for(int i=;i<to[pos].size();++i){
int tt=to[pos][i];
if(tt==fa)continue;
pii g =mine[tt][];
change(pos,tt);
getq(tt,pos);
v[tt]=v[pos]=;
mine[tt][]=g,mine[pos][]=make_pair(,n);
}
}
int blo;
int x[maxm],y[maxm],c[maxm]; int lt[maxn],rt[maxn];
int main() {
#ifdef local
freopen("inpp","r",stdin);
// freopen("outpp","w",stdout);
#endif
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)scanf("%d",&val[i]),v[i]=;
init_val();
for(int i=;i<n;++i){
int a,b;scanf("%d%d",&a,&b);
to[a].push_back(b);to[b].push_back(a);
}
dfs(,);
int now=;
while(m--){
int od,a,b;
scanf("%d",&od);
if(od==)scanf("%d",&now);
else{
scanf("%d%d",&a,&b);++cc;
w[now].push_back(node(cc,a,b));
}
}
getq(,);
blo=sqrt(sz);if(blo==)blo=;
for(int i=;i<=sz;++i)all[i].bel=all[i].l/blo; for(int i=;i<=sz;++i)++c[all[i].r];//基数排序部分
for(int i=;i<=n;++i)c[i]+=c[i-];
for(int i=;i<=sz;++i)y[c[all[i].r]--]=i; int en=n/blo;
for(int i=;i<=en;++i)c[i]=;
for(int i=;i<=sz;++i)++c[all[i].bel];
for(int i=;i<=en;++i)c[i]+=c[i-];
for(int i=sz;i;--i)x[ c[ all[y[i]].bel ]-- ]=y[i]; ll uu=; int L=,R=; for(int i=;i<=sz;++i){
query&ha=all[x[i]];
while(R<ha.r){
++R;
int k=val[dfsn[R]];
uu-=(ll)rt[k]*lt[k];
++rt[k];
uu+=(ll)rt[k]*lt[k];
}
while(R>ha.r){
int k=val[dfsn[R]];
uu-=(ll)rt[k]*lt[k];
--rt[k];
uu+=(ll)rt[k]*lt[k];
--R;
}
while(L>ha.l){
int k=val[dfsn[L]];
uu-=(ll)rt[k]*lt[k];
--lt[k];
uu+=(ll)rt[k]*lt[k];
--L;
}
while(L<ha.l){
++L;
int k=val[dfsn[L]];
uu-=(ll)rt[k]*lt[k];
++lt[k];
uu+=(ll)rt[k]*lt[k];
}
if(ha.ti)ans[ha.foo]+=uu;
else ans[ha.foo]-=uu;
}
for(int i=;i<=cc;++i)
printf("%lld\n",ans[i]);
return ;
}
wannafly 练习赛11 F 求子树(树上莫队+换根)的更多相关文章
- wannafly 练习赛10 f 序列查询(莫队,分块预处理,链表存已有次数)
链接:https://www.nowcoder.net/acm/contest/58/F 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 262144K,其他语言524288K 64 ...
- wannafly 练习赛10 E 数列查找(莫队+分块分块分块......)
链接:https://www.nowcoder.net/acm/contest/58/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit ...
- wannafly 练习赛11 E 求最值(平面最近点对)
链接:https://www.nowcoder.com/acm/contest/59/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit ...
- 【BZOJ3757】苹果树(树上莫队)
点此看题面 大致题意: 每次问你树上两点之间路径中有多少种颜色,每次询问可能会将一种颜色\(a\)看成\(b\). 树上莫队 这题是一道树上莫队板子题. 毕竟求区间中有多少种不同的数是莫队算法的经典应 ...
- 【BZOJ3460】Jc的宿舍(树上莫队+树状数组)
点此看题面 大致题意: 一棵树,每个节点有一个人,他打水需要\(T_i\)的时间,每次询问两点之间所有人去打水的最小等待时间. 伪·强制在线 这题看似强制在线,但实际上,\(pre\ mod\ 2\) ...
- SPOJ COT2 Count on a tree II (树上莫队,倍增算法求LCA)
题意:给一个树图,每个点的点权(比如颜色编号),m个询问,每个询问是一个区间[a,b],图中两点之间唯一路径上有多少个不同点权(即多少种颜色).n<40000,m<100000. 思路:无 ...
- BZOJ 4129: Haruna’s Breakfast [树上莫队 分块]
传送门 题意: 单点修改,求一条链的mex 分块维护权值,$O(1)$修改$O(S)$求mex...... 带修改树上莫队 #include <iostream> #include < ...
- 【XSY1642】Another Boring Problem 树上莫队
题目大意 给你一棵\(n\)个点的树,每个点有一个颜色\(c_i\),每次给你\(x,y,k\),求从\(x\)到\(y\)的路径上出现次数第\(k\)多的颜色的出现次数 \(n,q\leq 1000 ...
- 2018CCPC女生赛(树上莫队)
签到题这里久懒得写了. B - 缺失的数据范围 Total Submission(s): 2602 Accepted Submission(s): 559 题意:求最大的N,满足N^a*[log ...
随机推荐
- Python 入门之 软件开发规范
Python 入门之 软件开发规范 1.软件开发规范 -- 分文件 (1)为什么使用软件开发规范: 当几百行--大几万行代码存在于一个py文件中时存在的问题: 不便于管理 修改 可读性差 加载速度慢 ...
- 事件循环(EventLoop)的学习总结
前言 在学习eventloop之前,我们需要复习一下js的单线程和异步.虽说js是单线程的,但是在浏览器和Node中都做了相应的处理.如浏览器中的web workers(工作线程),Node中的chi ...
- React中富文本编辑器的技术选型调研
前言 富文本编辑器是项目中不可或缺的部分,目前市面上可以选择的富文本编辑器种类繁多,如何在项目中选择一款集轻量,美观,稳定,坑少,满足需求的富文本编辑器变成了团队中一个重要的问题. 现在项目中使用的是 ...
- 剑指offer-字符串的排列-数组-递归-动态规划-python
题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: 输 ...
- 生成二维码(java后端)
需要引入2个jar包: <dependency> <groupId>com.google.zxing</groupId> <artifactId>jav ...
- sqlserver2008 批量导出所有的作业
SQl server 代理 -- 选中作业 -- 按 F7,弹出 对象资源管理详细信息 ,里面对作业多选以后右键就有导出 sql的菜单了
- SAP发布wbservice,如果有权限管控的话,需要给这个webservice加权限
1. PFCG床架角色 2.在角色菜单上,添加其他,选中Authorization Default Values for Services 如下图 3.选中发布的webservice 后保存,如下图: ...
- poj 1664 放苹果(dfs)
放苹果 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 30284 Accepted: 19098 Description ...
- ARIMA模型
ARIMA模型(英语:Autoregressive Integrated Moving Average model),差分整合移动平均自回归模型,又称整合移动平均自回归模型(移动也可称作滑动),时间序 ...
- 引用vector里的元素被删除后,引用会怎么样?
引用的定义不多说,直接看做变量的别名就可以了.有一天写着写着代码,突然想到,如果对vector里某个元素设置引用后,将这个元素从vector里删除会怎么样?我思考了下,认为那个元素会被删除,但是引用还 ...