kruscal重构树略解

            我们先看一道题:Luogu P4197 Peaks

            这道题珂以用启发式合并+主席树来做

            那么强制在线呢?(bzoj 3551 [ONTAK2010]Peaks加强版)

            离线做法就不行了

            我们就要用一个叫做kruscal重构树的东西来解决这个问题

            克鲁斯卡尔重构树可以用来解决一类诸如“查询从某个点出发经过边权不超过val的边所能到达的节点”的问题

            首先不难发现,上面这个问题肯定是在最小生成树上走最优,其他边都可以不用去管

            kruscal构树的思想就是在建最小生成树的时候不是直接连边,而是新建一个节点,并把这个节点的值设为边权,然后令两个连通块的代表点分别作为它的左右儿子。然后令这个新节点成为整个连通块的代表点

            那么这样做有什么用呢?

            kruscal重构树有这样的性质:一个点的所有子树节点的权值都小于等于它的权值,并且从它开始逐渐向子节点移动,权值是单调不上升的。这个性质是显然的,因为我们在构造树的时候是从小到大插入的边,因此父亲节点的权值一定大于等于子节点的值

            查询时,首先可以在树上倍增得到当前查询点所能够到达的最远的祖先点,那么从这个点能够到达的符合边权限制条件的连通块中的节点,就是祖先点的子树中所有的叶节点

            然后我们按dfs序维护一个主席树上树就可以解决了

            完整代码(离线)

            #include <bits/stdc++.h>
            #define getchar nc
            #define N 200005
            #define M N<<4
            #define K 500005
            using namespace std;
            inline char nc(){
                static char buf[100000],*p1=buf,*p2=buf; 
                return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
            }
            inline int read()
            {
                register int x=0,f=1;register char ch=getchar();
                while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
                while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
                return x*f;
            }
            inline void write(register int x)
            {
                if(!x)putchar('0');if(x<0)x=-x,putchar('-');
                static int sta[20];register int tot=0;
                while(x)sta[tot++]=x%10,x/=10;
                while(tot)putchar(sta[--tot]+48);
            }
            struct node{
                int u,v,c;
                node(){}
                node(int u,int v,int c):u(u),v(v),c(c){}
                inline bool operator <(const node &b)const
                {
                    return c<b.c;
                }
            }E[K];
            struct edge{
                int to,next;
            }e[N];
            int head[N],tot;
            inline void add(register int u,register int v)
            {
                e[++tot]=(edge){v,head[u]};
                head[u]=tot;
            }
            int n,m,q,limit,dfn;
            int bin[25];
            int fa[N],val[N],f[N][20];
            int b[N>>1],h[N>>1];
            int ls[N],rs[N],rt[N],num;
            int sum[M],L[M],R[M],cnt;
            inline void mission(register int x)
            {
                for(register int i=1;bin[i]<=n;++i)
                    f[x][i]=f[f[x][i-1]][i-1];
            }
            inline void update(register int last,register int &now,register int l,register int r,register int x)
            {
                sum[now=++cnt]=sum[last]+1;
                if(l==r)
                    return;
                int mid=l+r>>1;
                if(x<=mid)
                    R[now]=R[last],update(L[last],L[now],l,mid,x);
                else
                    L[now]=L[last],update(R[last],R[now],mid+1,r,x);
            }
            inline int query(register int a,register int x,register int k)
            {
                int l=1,r=limit;
                for(register int j=18;~j;--j)
                    if(f[a][j]&&val[f[a][j]]<=x)
                        a=f[a][j];
                int v=rt[rs[a]],u=rt[ls[a]-1];
                if(sum[v]-sum[u]<k)
                    return -1;
                while(l<r)
                {
                    int tmp=sum[R[v]]-sum[R[u]],mid=l+r>>1;
                    if(tmp>=k)
                        v=R[v],u=R[u],l=mid+1;
                    else
                        v=L[v],u=L[u],r=mid,k-=tmp;
                }
                return b[r];
            }
            inline void dfs(register int u)
            {
                mission(u);
                ls[u]=++num;
                if(u<=n)
                    update(rt[num-1],rt[num],1,limit,h[u]);
                else
                    rt[num]=rt[num-1];
                for(register int i=head[u];i;i=e[i].next)
                    dfs(e[i].to);
                rs[u]=num;
            }
            inline int find(register int x)
            {
                return x==fa[x]?x:fa[x]=find(fa[x]);
            }
            int main()
            {
                n=read(),m=read(),q=read();
                bin[1]=1;
                for(register int i=2;i<=22;++i)
                    bin[i]=bin[i-1]<<1;
                for(register int i=1;i<=n<<1;++i)
                    fa[i]=i;
                for(register int i=1;i<=n;++i)
                    b[i]=h[i]=read();
                sort(b+1,b+n+1);
                limit=unique(b+1,b+n+1)-b-1;
                for(register int i=1;i<=n;++i)
                    h[i]=lower_bound(b+1,b+limit+1,h[i])-b;
                for(register int i=1;i<=m;++i)
                {
                    int u=read(),v=read(),c=read();
                    E[i]=node(u,v,c);
                }
                sort(E+1,E+m+1);
                dfn=n;
                for(register int i=1;i<=m;++i)
                {
                    int u=find(E[i].u),v=find(E[i].v);
                    if(u!=v)
                    {
                        val[++dfn]=E[i].c;
                        fa[u]=fa[v]=dfn;
                        add(dfn,u),add(dfn,v);
                        f[u][0]=f[v][0]=dfn;
                        if(dfn-n==n-1)
                            break;
                    }
                }
                for(register int i=1;i<=dfn;++i)
                    if(!ls[i])
                        dfs(find(i));
                while(q--)
                {
                    int v=read(),x=read(),k=read();
                    write(query(v,x,k)),puts("");
                }
                return 0;
            }

            完整代码(在线)

            #include <bits/stdc++.h>
            #define getchar nc
            #define N 200005
            #define M N<<4
            #define K 500005
            using namespace std;
            inline char nc(){
                static char buf[100000],*p1=buf,*p2=buf; 
                return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
            }
            inline int read()
            {
                register int x=0,f=1;register char ch=getchar();
                while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
                while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
                return x*f;
            }
            inline void write(register int x)
            {
                if(!x)putchar('0');if(x<0)x=-x,putchar('-');
                static int sta[20];register int tot=0;
                while(x)sta[tot++]=x%10,x/=10;
                while(tot)putchar(sta[--tot]+48);
            }
            struct node{
                int u,v,c;
                node(){}
                node(int u,int v,int c):u(u),v(v),c(c){}
                inline bool operator <(const node &b)const
                {
                    return c<b.c;
                }
            }E[K];
            struct edge{
                int to,next;
            }e[N];
            int head[N],tot;
            inline void add(register int u,register int v)
            {
                e[++tot]=(edge){v,head[u]};
                head[u]=tot;
            }
            int n,m,q,limit,dfn;
            int bin[25];
            int fa[N],val[N],f[N][20];
            int b[N>>1],h[N>>1];
            int ls[N],rs[N],rt[N],num;
            int sum[M],L[M],R[M],cnt;
            inline void mission(register int x)
            {
                for(register int i=1;bin[i]<=n;++i)
                    f[x][i]=f[f[x][i-1]][i-1];
            }
            inline void update(register int last,register int &now,register int l,register int r,register int x)
            {
                sum[now=++cnt]=sum[last]+1;
                if(l==r)
                    return;
                int mid=l+r>>1;
                if(x<=mid)
                    R[now]=R[last],update(L[last],L[now],l,mid,x);
                else
                    L[now]=L[last],update(R[last],R[now],mid+1,r,x);
            }
            inline int query(register int a,register int x,register int k)
            {
                int l=1,r=limit;
                for(register int j=18;~j;--j)
                    if(f[a][j]&&val[f[a][j]]<=x)
                        a=f[a][j];
                int v=rt[rs[a]],u=rt[ls[a]-1];
                if(sum[v]-sum[u]<k)
                    return -1;
                while(l<r)
                {
                    int tmp=sum[R[v]]-sum[R[u]],mid=l+r>>1;
                    if(tmp>=k)
                        v=R[v],u=R[u],l=mid+1;
                    else
                        v=L[v],u=L[u],r=mid,k-=tmp;
                }
                return b[r];
            }
            inline void dfs(register int u)
            {
                mission(u);
                ls[u]=++num;
                if(u<=n)
                    update(rt[num-1],rt[num],1,limit,h[u]);
                else
                    rt[num]=rt[num-1];
                for(register int i=head[u];i;i=e[i].next)
                    dfs(e[i].to);
                rs[u]=num;
            }
            inline int find(register int x)
            {
                return x==fa[x]?x:fa[x]=find(fa[x]);
            }
            int main()
            {
                n=read(),m=read(),q=read();
                bin[1]=1;
                for(register int i=2;i<=22;++i)
                    bin[i]=bin[i-1]<<1;
                for(register int i=1;i<=n<<1;++i)
                    fa[i]=i;
                for(register int i=1;i<=n;++i)
                    b[i]=h[i]=read();
                sort(b+1,b+n+1);
                limit=unique(b+1,b+n+1)-b-1;
                for(register int i=1;i<=n;++i)
                    h[i]=lower_bound(b+1,b+limit+1,h[i])-b;
                for(register int i=1;i<=m;++i)
                {
                    int u=read(),v=read(),c=read();
                    E[i]=node(u,v,c);
                }
                sort(E+1,E+m+1);
                dfn=n;
                for(register int i=1;i<=m;++i)
                {
                    int u=find(E[i].u),v=find(E[i].v);
                    if(u!=v)
                    {
                        val[++dfn]=E[i].c;
                        fa[u]=fa[v]=dfn;
                        add(dfn,u),add(dfn,v);
                        f[u][0]=f[v][0]=dfn;
                        if(dfn-n==n-1)
                            break;
                    }
                }
                for(register int i=1;i<=dfn;++i)
                    if(!ls[i])
                        dfs(find(i));
                int lastans=0,v,x,k;
                while(q--)
                {
                    if(~lastans)
                        v=read()^lastans,x=read()^lastans,k=read()^lastans;
                    else
                        v=read(),x=read(),k=read();
                    write(lastans=query(v,x,k)),puts("");
                }
                return 0;
            }
            相关文章
            相关标签/搜索
            管家婆精选心水资料中特网 天峻县| 沛县| 娱乐| 西昌市| 通州市| 旬阳县| 文安县| 柯坪县| 宝山区| 民权县| 广东省| 平泉县| 永顺县| 佛学| 耒阳市| 马山县| 吐鲁番市| 景泰县| 贺州市| 麻江县| 台山市| 渝北区| 尼木县| 邵东县| 池州市| 万安县| 视频| 阳高县| 潮安县| 天津市| 邳州市| 兴文县| 黄骅市| 将乐县| 新源县| 绥江县| 桑日县| 梧州市| 分宜县| 泰顺县| 望都县| 阜康市| 新蔡县| 托克逊县| 禄丰县| 新建县| 昭通市| 泾川县| 霸州市| 五峰| 庆云县| 邵东县| 湖南省| 喀什市| 错那县| 临潭县| 海口市| 通许县| 宜兰市| 那坡县| 河津市| 德清县| 瑞金市| 太康县| 南充市| 华坪县| 玛纳斯县| 澄江县| 大理市| 腾冲县| 涟源市| 宝山区| 白沙| 磴口县| 江安县| 卢氏县| 蒲江县| 玛纳斯县| 正阳县| 武夷山市| 柳河县| 平泉县| 渭源县| 昆明市| 通海县| 郁南县| 武夷山市| 黑水县| 河津市| 塔城市| 禹州市| 屯门区| 大名县| 平度市| 云南省| 武清区| 岐山县| 旺苍县| 从化市| 南阳市| 永丰县| 交口县| 巴青县| 福鼎市| 安平县| 兴宁市| 榆社县| 阿拉善左旗| 仁寿县| 锡林浩特市| 会泽县| 德钦县| 剑河县| 浮山县| 秦皇岛市| 聂荣县| 水城县| 全州县| 兴山县| 木兰县| 教育| 静乐县| 八宿县| 宁国市| 资源县| 柏乡县| 台前县| 崇文区| 德惠市| 德清县| 莆田市| 金山区| 和静县| 渝中区| 靖西县| 江门市| 景德镇市| 莎车县| 平和县| 阿瓦提县| 南皮县| 邵阳县| 中宁县| 临汾市| 农安县| 徐水县| 天镇县| 达拉特旗| 昌吉市| 宁蒗| 左云县| 图们市| 仪征市| 治多县| 咸丰县| 奉贤区| 墨江| 杭锦旗| 巴里| 甘肃省| 禹州市| 谷城县| 眉山市| 凤冈县| 巫溪县| 富平县| 姚安县| 南木林县| 始兴县| 黎川县| 时尚| 岫岩| 尉氏县| 安康市| 胶州市| 甘洛县| 临城县| 靖江市| 金乡县| 桑植县| 都江堰市| 太和县| 德州市| 溧水县| 蓝田县| 嵩明县| 平邑县| 太仆寺旗| 分宜县| 霍林郭勒市| 保亭| 彝良县| 长春市| 绥棱县| 泗水县| 花莲市| 洪江市| 石首市| 兰坪| 聂荣县| 西乌| 正阳县| 上犹县| 漯河市| 曲沃县| 肥东县| 神池县| 德钦县| 黎川县| 东港市| 资兴市| 富平县| 喀什市| 闻喜县| 漠河县| 缙云县| 衢州市| 岳阳市| 信阳市| 田林县| 勃利县| 黄平县| 肥城市| 乌兰察布市| 长宁区| 壤塘县| 苏尼特左旗| 周至县| 诸暨市| 新泰市| 岳阳县| 金阳县| 博湖县| 寻甸| 莱阳市| 呼玛县| 延庆县| 偏关县| 兴海县| 重庆市| 黄石市| 河西区| 深圳市| 罗城| 太谷县| 威远县| 垣曲县| 浮梁县| 荆州市| 嘉鱼县| 阳朔县| 乐至县| 井研县| 老河口市| 颍上县| 江源县| 志丹县| 舞阳县| 麦盖提县| 来宾市| 大洼县| 綦江县| 静乐县| 攀枝花市| 鹤峰县| 南投市| 东光县| 奉贤区| 全椒县| 安龙县| 鲁甸县| 奎屯市| 大新县| 鞍山市| 博湖县| 恩平市| 肥乡县| 文登市| 沙湾县| 庄河市| 东阿县| 兴仁县| 临夏县| 定西市| 兰坪| 新兴县| 韩城市| 济阳县| 珲春市| 普陀区| 桐城市| 合作市| 英德市| 莱阳市| 霍州市| 汶川县| 日土县| 磐安县| 雷州市| 平昌县| 繁峙县| 衡阳县| 出国| 遵义市| 临夏县| 乡宁县| 柳林县| 会宁县| 金沙县| 遂溪县| 永安市| 缙云县| 元谋县| 德清县| 揭西县| 衡阳市| 留坝县| 崇文区| 新丰县| 定边县| 黑水县| 锦屏县| 绍兴县| 河南省| 高安市| 建湖县| 宁阳县| 宿松县| 怀仁县| 府谷县| 祁东县| 文成县| 平塘县| 霍林郭勒市| 青河县| 临海市| 凤凰县| 麦盖提县| 翁牛特旗| 滕州市| 来凤县| 丰顺县| 马山县| 临武县| 廉江市| 铁力市| 黔东| 无棣县| 迭部县| 寿阳县| 双峰县| 湘西| 红桥区| 新巴尔虎左旗| 庐江县| 灵璧县| 绥棱县| 朝阳区| 西安市| 湖北省| 彰武县| 巴马| 晋中市| 镇沅| 苗栗县| 遂溪县| 澳门| 安塞县| 彭山县| 舞阳县| 马关县| 斗六市| 响水县| 松滋市| 桃园市| 天水市| 新疆| 廉江市| 华亭县| 石阡县| 宝丰县| 浦东新区| 文昌市| 清徐县| 津市市| 孟村| 泰来县| 海丰县| 临泉县| 合川市| 彭阳县| 集贤县| 宿松县| 台州市| 牙克石市| 图木舒克市| 北票市| 巩留县| 红河县| 台山市| 福鼎市| 阳曲县| 临高县| 崇文区| 长岛县| 阿勒泰市| 公主岭市| 连云港市| 宜黄县| 贺州市| 开平市| 水城县| 安康市| 合水县| 彰化市| 乌鲁木齐县| 丰原市| 凤翔县| 封丘县| 唐海县| 吉水县| 山阳县| 漠河县| 汉源县| 视频| 康平县| 永修县| 鄂州市| 云南省| 伊吾县| 贺兰县| 邢台市| 赣榆县| 静乐县| 米泉市| 通海县| 惠东县| 徐汇区| 华亭县| 蒙山县| 锡林浩特市| 阿拉善右旗| 游戏| 大同市| 东海县| 老河口市| 嵩明县| 青海省| 任丘市| 浮山县| 武邑县| 托克逊县| 牡丹江市| 鹿泉市| 武山县| 太白县| 五大连池市| 墨竹工卡县| 罗山县| 澎湖县| 周宁县| 驻马店市| 和政县| 闸北区| 遂平县| 陆川县| 崇左市| 酒泉市| 永济市| 白沙| 宁乡县| 汝阳县| 文安县| 江油市| 南岸区| 萍乡市| 印江| 开鲁县| 碌曲县| 蕲春县| 吉水县| 华蓥市| 离岛区| 大埔区| 天祝| 云安县| 龙里县| 桂林市| 津市市| 全南县| 大石桥市| 同德县| 九寨沟县| 宝应县| 高尔夫| 达州市| 将乐县| 社会| 武义县| 云南省| 通道| 化德县| 孝义市| 陆河县| 灵山县| 深圳市| 正阳县| 阜阳市| 山阴县| 万全县| 大足县| 太和县| 依兰县| 察雅县| 滁州市| 平昌县| 宁武县| 平原县| 华宁县| 凌源市| 雅江县| 东莞市| 兴仁县| 连山| 巴南区| 海南省| 定安县| 西青区| 收藏| 南阳市| 峨山| 南康市| 砚山县| 庆云县| 英吉沙县| 乳山市| 班戈县| 凌海市| 凤山县| 甘肃省| 郑州市| 云阳县| 千阳县| 陆川县| 会昌县| 铜山县| 定州市| 彰化县| 大邑县| 井陉县| 遂宁市| 如东县| 景宁| 乐亭县| 驻马店市| 册亨县| 霍山县| 同江市| 临邑县| 东山县| 柘城县| 沾化县| 武穴市| 利津县| 铜鼓县| 吕梁市| 金川县| 新乡市| 柳林县| 通海县| 遂川县| 福海县| 宁德市| 定结县| 河东区| 永定县| 城口县| 清新县| 普格县| 罗甸县| 张掖市| 周至县| 静宁县| 周至县| 民勤县| 田东县| 丽水市| 青河县| 隆回县| 吉林市| 自治县| 正定县| 凤台县| 韶关市| 循化| 香港| 邵武市| 秭归县| 溆浦县| 广宁县| 洪湖市| 枝江市| 赣榆县| 土默特右旗| 洞头县| 博乐市| 九龙县| 牙克石市| 吉木萨尔县| 喜德县| 孟连| 林口县| 广元市| 皮山县| 灯塔市| http://www.ykjjsf.fit http://wap.xflnqt.fit http://pqoxon.fit http://wap.rtocoi.fit http://m.jdylsl.fit http://bm1961xerchandisez.fit http://wap.optcvs.fit http://wap.bm1961xentionz.fit http://www.quybtv.fit http://wap.egqjqt.fit http://m.zxjqux.fit http://wap.aoecrm.fit http://www.ktjgvn.fit http://wap.nbaudk.fit http://www.lknemu.fit http://wap.yfuhvf.fit http://kazqqh.fit http://www.sdlrot.fit