您的位置:首页 > 其它

2017.9.23 Count on a tree 思考记录

2017-09-23 17:41 232 查看
这个题就是把区间第k大搬到了树上、、

于是想到链剖、但链剖是要支持区间合并的,第k大显然不可以合并,那怎么办呢

所以就可以容斥,,把所有重链起点终点用两个rt截下来,再把每个+和每个-离散下来,然后由于主席树查找是logn的,离散的点最多有logn对,

所以复杂度是(2*nlog^2n)  可以卡过、

网上的题解是dfs序。。感觉dfs序好想比较神奇,,但已经不知道用多少链剖水过dfs了、

虽然很难写,但写完了比较好调,毕竟难点不在分类讨论、终于1A主席树+链剖辣

码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define N 100005
#include<map>
using namespace std;
int fu
,sz
,a,syg
,cnt,zj[100],sd[100],b,m,n,c,d
,siz[N*30],sta1[100][100],sta2[100][100],ch[N*30][2],dui
,ans,fd
,tot,top
,rt
,hson
;
vector<int>v
;
void dfs1(int o,int fa,int dis)
{
int i;
fu[o]=fa;
sz[o]=1;
d[o]=dis;
for(i=0;i<v[o].size();i++)
{
int nd=v[o][i];
if(nd==fa)continue;
dfs1(nd,o,dis+1);
if(sz[hson[o]]<sz[nd])hson[o]=nd;
sz[o]+=sz[nd];
}
}
void up(int o)
{
siz[o]=siz[ch[o][0]]+siz[ch[o][1]];
}
void jia(int o,int l,int r,int last)
{
if(l==r)
{
siz[o]=1;
return ;
}
int mid=(l+r)>>1;
if(c<=mid)
{
ch[o][0]=++tot;
jia(ch[o][0],l,mid,ch[last][0]);
ch[o][1]=ch[last][1];
}
if(c>mid)
{
ch[o][1]=++tot;
jia(ch[o][1],mid+1,r,ch[last][1]);
ch[o][0]=ch[last][0];
}
up(o);
}
int wr;
void dfs2(int o,int tap)
{
int i;
top[o]=tap;
syg[o]=wr;
rt[o]=++tot;
//cout<<o<<" --> "<<rt[o]<<endl;
c=dui[o];
jia(rt[o],1,n,rt[wr]);
wr=o;
if(hson[o]!=0)dfs2(hson[o],tap);
for(i=0;i<v[o].size();i++)
{
int nd=v[o][i];
if(nd==fu[o]||nd==hson[o])continue;
dfs2(nd,nd);
}
}
void cha(int l,int r)
{
if(l==r)
{
ans=fd[l];
return;
}
int mid=(l+r)>>1;
int i,lin=0;
for(i=1;i<=cnt;i++)
lin+=siz[ch[sta1[tot][i]][0]];
for(i=1;i<=cnt;i++)
lin-=siz[ch[sta2[tot][i]][0]];
if(lin<c)
{
c-=lin;
++tot;
for(i=1;i<=cnt;i++)
sta1[tot][i]=ch[sta1[tot-1][i]][1],sta2[tot][i]=ch[sta2[tot-1][i]][1];
cha(mid+1,r);

}else
{
++tot;
for(i=1;i<=cnt;i++)
sta1[tot][i]=ch[sta1[tot-1][i]][0],sta2[tot][i]=ch[sta2[tot-1][i]][0];
cha(l,mid);
}

--tot;

}
void work(int x,int y)
{
ans=0;cnt=0;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])swap(x,y);
sd[++cnt]=syg[top[x]];
zj[cnt]=x;
x=fu[top[x]];
}
if(d[x]>d[y])swap(x,y);
sd[++cnt]=syg[x];
zj[cnt]=y;	//	cout<<cnt;
tot=0;
++tot;
int i;
for(i=1;i<=cnt;i++)
sta1[tot][i]=rt[zj[i]],sta2[tot][i]=rt[sd[i]];
cha(1,n);
}
struct woc
{
int a,id;
}s
;
bool cmp(woc a,woc b)
{
return a.a<b.a;
}
int main()
{
int i,x,y,z;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d",&s[i].a);
s[i].id=i;
}
sort(s+1,s+1+n,cmp);
for(i=1;i<=n;i++)
{
dui[s[i].id]=i;
fd[i]=s[i].a;
}
for(i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
dfs1(1,0,1);
dfs2(1,1);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&c);
x=x^ans;
work(x,y);
if(i!=m)printf("%d\n",ans);
else printf("%d",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: