首页 > 其他分享 >luogu P5311 [Ynoi2011] 成都七中

luogu P5311 [Ynoi2011] 成都七中

时间:2022-08-24 21:35:46浏览次数:106  
标签:七中 int luogu Ts Si && using P5311 define

题面传送门

首先考虑暴力怎么做。按照UNRD2T2找到每个联通块最高点的套路,我们可以找到每个询问点的祖先中,这个点到祖先路径上的点全部位于\([l,r]\)区间中的最浅的祖先,那么这个点所在的联通块可以表示为这个点子树内,到这个点路径上点全部位于\([l,r]\)内的点所构成的联通块,然后可以暴力数颜色。

我们发现整个预处理部分如果树是随机的就可以过了,但是这个高度显然不随机。

发现这个问题对树的形态要求不是很高,考虑建立点分树,然后预处理树上倍增可以快速查询,就可以暴力往上跳找到这个祖先,然后也可以暴力遍历子树找到每个点到根节点取值区间,当前的询问区间要包含这个区间才可以算入答案。

在线不太好做,考虑离线到每个点分树上面的点上,然后将询问和点都按照右端点排序,这样的话可以对右端点扫描线,并且维护每个颜色最近的左端点,就可以用一个树状数组二维数点了。

时间复杂度\(O(n\log ^2n+q\log n)\),常数挺小的毕竟瓶颈在树状数组和排序。

code:

#include<bits/stdc++.h>
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((k+1)*(x)+(y))
#define R(n) (rnd()%(n)+1)
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using ll=long long;using db=double;using lb=long db;using ui=unsigned;using ull=unsigned ll;
using namespace std;const int N=100000+5,M=(N*200)+5,K=(1<<16)+5,mod=998244353,M1=998244353,M2=1e9+7,Mod=mod-1;const db eps=1e-5;
int n,m,W[N],x,y,z,Ans[N];vector<int> S[N];
struct Ques{int x,y,z;}D[N];vector<Ques> Q[N];bool cmp(Ques x,Ques y){return x.y<y.y;}
namespace DIS{
	int fa[N][20],lg[N],Mx[N][20],Mi[N][20],d[N];
	void Make(int x,int La){fa[x][0]=La;Mx[x][0]=Mi[x][0]=x;d[x]=d[La]+1;for(int i=1;fa[x][i-1];i++) fa[x][i]=fa[fa[x][i-1]][i-1],Mx[x][i]=max(Mx[x][i-1],Mx[fa[x][i-1]][i-1]),Mi[x][i]=min(Mi[x][i-1],Mi[fa[x][i-1]][i-1]);for(int i:S[x]) i^La&&(Make(i,x),0);}
	void BD(){for(int i=2;i<=n;i++) lg[i]=lg[i/2]+1;Make(1,0);}
	pair<int,int> Qry(int x,int y){int Xm=0,Im=1e9;d[x]<d[y]&&(swap(x,y),0);while(d[x]^d[y]) Xm=max(Xm,Mx[x][lg[d[x]-d[y]]]),Im=min(Im,Mi[x][lg[d[x]-d[y]]]),x=fa[x][lg[d[x]-d[y]]];if(x==y) return {min(Im,x),max(Xm,x)};for(int i=lg[d[x]];~i;i--) fa[x][i]^fa[y][i]&&(Xm=max(Xm,max(Mx[x][i],Mx[y][i])),Im=min(Im,min(Mi[x][i],Mi[y][i])),x=fa[x][i],y=fa[y][i]);return {min(Im,min(fa[x][0],min(x,y))),max(Xm,max(fa[x][0],max(x,y)))};}
} 
namespace Tree{int f[N];void Ins(int x,int y){while(x<=n) f[x]+=y,x+=x&-x;}int Qry(int x){int Ans=0;while(x) Ans+=f[x],x-=x&-x;return Ans;}}
namespace DT{
	int Dh,f[N],g[N],Ct,Rt,Si[N],fa[N],vis[N],R;vector<int> G[N];void GI(int x,int La){Ct++;for(int i:S[x]) i^La&&!vis[i]&&(GI(i,x),0);}
	void DP(int x,int La){f[x]=0;Si[x]=1;for(int i:S[x]) i^La&&!vis[i]&&(DP(i,x),Si[x]+=Si[i],f[x]=max(f[x],Si[i]));f[x]=max(f[x],Ct-Si[x]);f[x]<f[Rt]&&(Rt=x);}
	void BD(int x,int La){Ct=0;GI(x,0);Rt=0;DP(x,0);x=Rt;La&&(G[La].PB(x),fa[x]=La);vis[x]=1;for(int i:S[x]) !vis[i]&&(BD(i,x),0);}
	int Jp(int x,int l,int r){int Ans=x,Id=x;pair<int,int> Ts;while(x) Ts=DIS::Qry(x,Id),Ts.first>=l&&Ts.second<=r&&(Ans=x),x=fa[x];return Ans;}
	void Push(int x,int Id){pair<int,int> Ts=DIS::Qry(x,Id);D[++Dh]=(Ques){Ts.first,Ts.second,W[x]};for(int i:G[x]) Push(i,Id);}
	void Solve(){
		int i,j;for(i=1;i<=n;i++){
			Dh=0;Push(i,i);sort(D+1,D+Dh+1,cmp);sort(Q[i].begin(),Q[i].end(),cmp);R=1;for(Ques d:Q[i]){
				while(R<=Dh&&D[R].y<=d.y) g[D[R].z]&&(Tree::Ins(g[D[R].z],-1),0),g[D[R].z]=max(D[R].x,g[D[R].z]),Tree::Ins(g[D[R].z],1),R++;Ans[d.z]=Tree::Qry(d.y)-Tree::Qry(d.x-1);
			}for(j=1;j<R;j++) g[D[j].z]&&(Tree::Ins(g[D[j].z],-1),g[D[j].z]=0);
		} 
	}
}
int main(){
	freopen("1.in","r",stdin);
	int i,j;scanf("%d%d",&n,&m);for(i=1;i<=n;i++) scanf("%d",&W[i]);for(i=1;i<n;i++) scanf("%d%d",&x,&y),S[x].PB(y),S[y].PB(x);DIS::BD();DT::f[0]=1e9;DT::BD(1,0);
	for(i=1;i<=m;i++) scanf("%d%d%d",&x,&y,&z),Q[DT::Jp(z,x,y)].PB({x,y,i});DT::Solve();for(i=1;i<=m;i++) printf("%d\n",Ans[i]);
}

标签:七中,int,luogu,Ts,Si,&&,using,P5311,define
From: https://www.cnblogs.com/275307894a/p/16622076.html

相关文章

  • 【luogu AT2366】Prefix Median(DP)
    PrefixMedian题目链接:luoguAT2366题目大意给你一个长度为2n-1的序列,你可以任意排序它们,问你有多少个不同的b数组。b数组的第i位为a数组1~2i-1区间的数的......
  • 【luogu P2508】圆上的整点(高斯素数模板)
    圆上的整点题目链接:luoguP2508题目大意给你一个圆,问你圆周上有多少个点的坐标是整点。思路考虑一个东西叫做高斯整数。其实它是复数,是\(a+bi\)中\(a,b\)都是整......
  • luogu P1488 肥猫的游戏
    肥猫的游戏P1488肥猫的游戏-洛谷|计算机科学教育新生态(luogu.com.cn)题目描述野猫与胖子,合起来简称肥猫,是一个班的同学,他们也都是数学高手,所以经常在一起讨论数......
  • luogu P1721 [NOI2016] 国王饮水记
    题面传送门首先我们发现,一定不会有低于\(h_1\)的参与操作的过程。然后考虑一个\(x\)与比它大的\(y<z\),则发现一定是先\((x,y)\),再\((\frac{x+y}{2},z)\)更好。因为这样......
  • luogu P8293 [省选联考 2022] 序列变换
    题面传送门因为WC2022考了这种构造,所以下意识将括号序列建树。手玩一下发现第一个操作实际上是干了这个事情:也就是说把用其中一个括号将另一个同层括号在树上移到了下......
  • luoguP3521 [POI2011]ROT-Tree Rotations【线段树】
    你要写热,就不能只写热。要写酷暑,写骄阳,写他人耳闻便生恐的炙烤和炎灼。要写白日出门一刻便肤色黝黑,背心透彻。写求雨心切,写出行伞遮。写夜晚不停的风扇和蝉聒。写鸡......
  • luoguP3224 [HNOI2012]永无乡【线段树,并查集】
    洞庭青草,近中秋,更无一点风色。玉鉴琼田三万顷,着我扁舟一叶。素月分辉,明河共影,表里俱澄澈。悠然心会,妙处难与君说。应念岭表经年,孤光自照,肝胆皆冰雪。短发萧骚襟袖冷,稳泛......
  • 【luogu CF1710C】XOR Triangle(数位DP)
    XORTriangle题目链接:luoguCF1710C题目大意给你一个数n,要你求有多少个满足条件的a,b,c使得它们两两异或得到的三个值可以得到一个非退化三角形。其中a,b,c值域在......
  • 【$dp$】$\text{LuoguP6570}$ 优秀子序列
    \(\text{LuoguP6570}\)优秀子序列读完题大概能yy到一个转移,即枚举两个不相交的子集然后转移。其实这题的顺序都无所谓,应该排个序,或者直接在值域上操作。\(DP\),用\(f......
  • 【luogu CF1710B】Rain(差分)(性质)
    Rain题目链接:luoguCF1710B题目大意给你若干个函数,每个函数是一个45度往上线段和往下线段接在一起,两个长度一样,y轴从0出发的。然后对于每个函数,求把它以外的所有......