模拟赛总结(三)

2024.9.16

重新定义饮料为一大杯冰沙

胃:这把生死局(指抿一口就开始起反应...)

早上就不停反呕,下午整这一出真是笑嘻了

T1 不相邻集合

以为贪心假的,结果对了

就是对新加的数看看有没有左邻右舍被取过,没有就计入答案

code

T2 线段树

暴力20

考虑到线段树开点方式,点编号之和肯定可以写成一次函数,具体的,设fn,x表示根为x,有n个叶子是的和,那么fn,x=kn×x+bn

然后有关系

fn,x=fn2,2x+fn2,2x+1+x

代入表达式可得:

{kn=2(kn2+kn2)+1bn=bn2+bn2+kn2

可以记忆化处理

然后正常跑查询,如果找到[l,r]在询问区间内,贡献就是krl+1×id+brl+1

byd mid没开ll耗掉不少时间,被#define int long long教育力

code

T4 园艺

听说数据很水最多枚举两个拐点可过..

正解鞋油+单队,感觉和之前掉馅饼的题很像

std1
std2

2024.9.22

菜死了

T1 自然数

下洗了,不会

先求出[1,i]的mex,记为mexi这个数组单调不降。然后记录ai在后面第一次出现的位置nxti

接下来枚举左端点,每次移动都为删掉一个x=al,然后mex中大于x的值就会被改成x,修改区间右端点就是nxtl1,左端点需要二分找第一个大于x的点,可以通过记录最大值实现

然后上线段树做区间修改,区间最值,区间求和即可

code

T2 钱仓

手膜膜错辣

改过来后发现就是贪心,然后存在这样一个点:该点后面的点的货物不会运到该点前面

这个点满足是最大子段和的起点(意思就是有足够多的货补给后面),由此处破环成链贪心即可

code

T3 游戏

考场上拿无穷近似推了个贼像的式子,然而还是遗憾离场

std

code

T4 暴雨

暴力搜索20

正解大炮,???

2024.9.28

T1 一般图最小匹配

贪心可以有75,但是考场上RE了一半多,后来使用魔法常数就OK

damn

整洁大炮

先对a【排序,这样后取相邻的一定最优

定义dpi,j,0/1表示到第i个数匹配了j对,并且第i个数没有用上

{dpi,j,0=min(dpi1,j,0,,dpi1,j,1)dpi,j,1=dpi1,j1,0+aiai1

使用滚动优化

code

T2 重定向

暴力枚举删除位+填数有一半分

考虑到字典序最小,使用贪心

minnum表示最小的未填数,minni表示aian中最小的数

  • ai=0

    如果minn_i < minnum,就要把minni删掉往这里放

  • ai0

    • ai>ai+1,则删掉ai更优
    • ai+1=0,如果ai>minnum,那么删掉ai更优

可以用优先队列维护要填的数

  • 注:在初始化优先队列中,循环上界为n时会RE,要改为n+1不知道为甚莫

code

T3 斯坦纳树

T4 直径

再戳

2024.10.2

障保龄而东之,回暴力于既倒

T2 肥胖

忘了可以从1走到其他点开吃,直接成10分,还都是1...

为了成功,肯定想要把限制放大点

于是可以建最大生成树

然后考虑选择的边中最小的,设为(u,v,w),此时有一个结论:先吃完一个子树再去吃另一个不劣于反复横跳

证明的话,考虑反复横跳吃的某一步肯定是吃了一棵子树的最后一个然后跳到另一个,此时经过(u,v,w)时的宽既有一棵子树的所有糖还有另一棵子树的一些糖,那还不如全吃完一棵,然后只经过一次(u,v,w)到另一棵树里吃吃吃

然后考虑答案,设sumu表示u字数内糖果总和,ansu表示吃完u为根的子树的最大初始体宽

假设从以u为根到以v为根,此时一个是要保证能过边,即wsumu,一个是要能吃完v树,就是ansvsumu,两答案取min,反之同理,u,v互换即可,最后两个min取个max即可

注:由于一开始ansi未求出,所以初始化成极大值

code

T3 分摊

看到分数吓似了

实际上大概是这样:只有儿子全满了自己才开始存钱

v为与当前点u有同样父亲的兄弟节点,那么父亲至少有x+min(sumv,x)块钱才能保证u拿到x块钱,其中sumvv的子树和

然后打log的话考虑倍增,但是略有不同

考虑到增量的维护,由于每一层都要和x比大小来产生贡献,所以一口气跳太多的话增量可能不能统一计算,会很麻烦

考虑一次跳跃,当上面的min等于xx会翻倍,此时可能计算方式不同,那么到这个点之前的路径的计算方式一样,那么另设一个gu,i表示当u2i级时,xgu,i时计算方式一样,g可以在维护增量的时候一并求得

那么就可以统一计算:二分min的分界点,左边计入子树和,右边计入若干个x

code + 注释

T4 修路

暴力有27

暴力时发现交点在圆内当且仅当两个由端点形成的区间严格相交(不取等)

由此可以维护区间,打log可以使用线段树一类物质

详情

code

T1 战争

口胡可得31

std

2024.10.3

亲手杀死整洁

T2 寻宝

看到传送门单向直接ban掉并查集,事后发现可以在并查集上建单向边跑暴力,毕竟最多100条边...

code

T1 构造字符串

手玩出30

正解就是相同的合并成块,然后(xi+zi,yi+zi)这两处一定不同,连边,非法就是块内有边

然后填数,块内有位置填了直接染掉即可,否则求mex即可

code

T3 序列

官方题解:

容易发现这是一个与斜率有关的题目,这种题目通常通过维护凸包,或者李超树维护
跨过pi的区间容易转化为:以pi为右端点的最优+以pi+1为左端点的最优
两个问题同理,以右端点(pi)为例
sai=j=1iajsbi=j=1ibj
最优即max1lr{(sarsal1)k(sbrsbl1)}
sarksbr+max0l<r{ksblsal},离线之后李超树维护直线即可
时间复杂度为O(nlogn),常数略大,空间复杂度为O(n)

往李超上套,就是把k当成x轴去搞

附李超讲解

附李超板题

70分流产代码

T4 构树

gugugugugugu~

2024.10.4

人死了一白天晚上才缓过来

T1 玩游戏

贪心写假了

不能只看挪动一位下左右谁最优,可能当前并入一个相对较大的数但是可以再并一个很小的负数,所以要用前缀和分别把左右指针推到极小处,考虑到极小处不一定是端点,所以要反着从端点往极小处跑,同样用前缀和实现

code

T2 排列

std

code

T3 最短路

std太吊

将返回等价为建反边后的前往,然后用dijkstra分别推进两个支路,使用bitset助力维护

disx,y表示从1走正边到x,走反边到y(从y返回1)的答案

code

T4 矩形

矩形重叠想到扫描线,但不会写

std

code

2024.10.5

T1 送花

从左往右扫,贡献是[1/lsti+1,i],然后扫到重复颜色时要删贡献,考虑到每次从1开始删会重复,所以删除区间是[1/lstlsti,lsti]

code

T2 星空

n300起手Floyd45

考虑转换坐标系

将原坐标系顺时针旋转45度,那么原来的坐标(x,y)就会变成(xy,x+y),设为(x,y)接着发现原坐标系中的距离变成了min(|Δx|,|Δy|),那么距离为0的点就是xy相同的点,使用并查集合并

最小距离的话就分别按x,y排序,在x/y变化处作差比较并记录所在块的编号,那么个数就是记录的每对块的size乘积的和,注意去重

code

T3 零一串

吊炸天

std

code

T4 Revive

线段树 + dfn + 树状数组...

std

2024.10.6

虚死了

不太想写东西,扔std得了

std1

std2

T1b

code

T2 竞赛图

code

T3 糖果

code

T4

code

2024.10.7

题目标题说得对

T1莓良心

糖,以为SegmentTree,把绝对值拆成max,min...

若干个区间相交的标志:maxl<=minr,此时所有数字没贡献

对于剩余未相交区间,在[minr,maxl]中间取数最优,此时所有数字贡献为maxlminr,乘上区间数目

每次更新maxl,minr都会少两个区间,求贡献时还要算上他自己

code

T3 团不过

正难则反

fi表示有i堆石子时的非法数量,gi表示总数

gi很好求,就是全排列:gi=A2n1

考虑求fi

既然要让异或和为0,那么不妨直接让第i堆石子数等于前i1堆石子数的异或和,此时要求前i1堆异或和不为0,有gi1fi1种,然后考虑重复的情况,第i堆和前面某一堆重复,那么剩下的i2堆异或和就是0,一共有i1堆,重复值的个数为2n1(i2)(重复的两堆和剩下的要互异),所以减去(i1)×fi2×(2ni+1)

答案:gnfn

T2 尽梨了

枚举b1的个数,设为c,设当前行1的个数为k

  • k<c : 有一些b的位置是1,而矩阵中是0,那么a对应位置就要放0

  • k>c : 同理,a只能放1

  • k=c : 此时b可以全部接住1a可以随便选

考虑计算

注意到k=c时要求所有k=c的行相同,判定稍后说,此时b唯一确定,所以方案数是2num

如果不存在k=c的行,那么b不确定,此时需要求出k<c至少需要多少个1,以及k>c中至少需要多少个0,后者可以求出至多有多少个1,至多与至少的差是备选位置数量,然后可以选的有cminn种,是个组合数

二者相互独立

接下来考虑判定合法,考虑到b要接住所有k<=c的行的1k>=c0,所以可以求并,那么前后夹击一下,pre1的并,nxt0的并,根据第二种情况可得,在c相同时,nxt为1的为pre必须为1而且nxt1数量 pre1数量,由此判断

code

T4 七负我

特殊性质(菊花图)提示我们均分最优,实际上确实如此,证明可以看看,接着就是求最大团,可以使用BK,就是一个搜索

code

2024.10.8

简单考了一场以替换月考

T1 哈希结果空间小了 T2 Tarjan忘了 T3 贪心假了...

放个链接

2024.10.13

都想到一点但不多

T1 Hunter

其实很简单,想复杂了

只有其他猎人在1号猎人之前死掉才会有1发的贡献,而根据成正比可得猎人i1前面死的概率为wiwi+w1,累加即可

code

T2 Defence

一眼看出是最长连续0的长度,但是暴力都炸了

有坑:如00100,需要4次,所以还有情况就是左右两端连续最长0的和

使用线段树合并,维护区间最大0,左右端最多0,在区间衔接处分讨处理端点0的数量,因为可能出现整个区间全是0的情况

code

T3 Connect

一眼最大生成树然后加回去一部分删的边,但是不好维护,因为可能加着加着就把儿子连起来成新路径了

后来想到给1n的“主链”上加东西,但是被题目搞懵了一下就下考了(输出给的是删掉边和最小,但题目说的是剩余边最大和,我直接****)

使用状压,预处理出所有能往主链上挂的东西sumS,然后处理衔接边cjS,i,之所以分开是因为挂的东西一点不在主链上,但是衔接的有一端在主链上,有一端在挂件里。(S是点集,i是在主链上的一点)

然后dp的时候一边延长主链一边挂东西就行了

code

2024.10.14

byd被wx和hl双重问候

T1score and rank

思路比较接近std,想到用堆维护

解释:遇到负数就把他摆平,如果当前总和小于负数绝对值就直接将总和置为0

code

T2 HZOI大作战

一眼倍增,不会维护...

解释:等价于重定义fu,i表示从u开始进行2i次交换后到达的点,维护方式和lca基本一致

code

T4 gtm和joke的星球

斯坦纳树板子,原理就是最终连通图必定是个树,使用状压进行两种操作:

1.合并:将有相同根的点集合并

2.换根:使用最短路更新点集的根使得边权和尽可能的小

对每个点先进行第一步,再对整个点集进行第二步

code

T3 Delov的旅行

只能意会..

code

2024.10.15

T1 限速(speed)

比较简单,建出最小生成树,如果树内最大边大于k,直接统计答案,否则枚举剩下的边找更优的替换

code

T2 酒鬼 (drunkard)

把题审成部分分了,就只有部分分了(27pts)

使用set维护,因为线索相互影响,要按时间排序再搞

发现pi=1时非常麻烦:拥有同一个minpi=1的时间满足奇偶性相同,比如时刻为1,3,5,7min都是1,所以如果插入不同奇偶性时刻t,比如t=4时在1,那么min会变成5,因为单看4,它的min0,不符合1,3,但是还可以不走,所以min5,因此再用一个set单独维护pi=1的时刻用于更新min。但还有一种情况:插入100的话min会变成7+1=8,所以还要分类:如果t大于最大,新的min就是最大值加一,否则就是t+1,后者还要把比t+1小的值删掉

但是还有一些线索会影响minn的奇偶性:时间上距离min最近的点。还是上面的1,3,5,7,插入10,3,会发现min不能是1了,但min=8可以,所以还要改。而且最近点也要更新,一旦更新就还要去维护pi=1的时刻...

其他线索的维护就比较简单:插入set后找前驱后继,满足以下两点即可:

  • |ΔT|>=dis

  • |ΔT|dis=2k

后一条在判断时间上距离min最近的点时也用到了

再加上特判有没有前驱后继等乱七八糟的细节 以及调试,长度来到惊人的3k

code

T3 距离(distance)

乱搞40

枚举点对,形成的贡献作用范围是1lca的链,树剖+线段树维护即可有70

差点没T2std长.....

T4 团队选拔(selection)

2024.8.6 T4原题 战绩可查

2024.10.16

糖死了把文件工工整整放到D盘忘交了...

T1 第一题

睡了导致什么也没有写...

只要占领全部叶子,其他点就占完了,所以考虑怎么占完叶子

占领一个叶子节点要么从其他叶子转移,要么从根新派一个兵,对于前者事先按照深度排序,然后对于每个叶子决策两种方式计算

code

T2 第二题

二分答案,然后遍历所有点把差抹平到二分值以下,计算所需代价是否超过K40分抹一遍即可,要获得90多分要抹十遍以上,最高95

考虑换一种方式:建图遍历,用类似Dij的方式搞,优化方案是先对所有点按权值排序(方式同dij),然后利用特殊性质用两个队列模拟Dij砍掉优先队列的log,执行一遍即可

code

T3 第三题

数位dp,定义dpi,j,0/1,0/1表示前i位一共有j1,卡/不卡下界(L),卡/不卡上界(R)

利用pairfirst存排名,second存和。考虑到只要有一位不卡上界后面的就都一定不卡,所以要按位与

考虑怎么判断卡不卡界限(由于对区间所有数排序所以初始状态下一定卡)

对于上界,当前在第i位,如果这一位是0,那没办法,因为前面一直卡着,选1的话就大于上界了,卡的状态为1。相反,如果是1,就有了不卡的机会,状态为0,发现刚好是异或的关系。下界刚好与上界相反,不用异或

更多细节看代码

code

T4 第四题

大炮

大肾tj

code

2024.10.17

T1 传送 (teleport)

分别按照x,y排序,每次排完序后给相邻边连边,最后跑最短路即可

code

T2 排列 (permutation)

考虑到最多只有10的数可能会使得gcdk,称为关键数,不妨状压这十个数的状态进行大炮

dpi,s,j表示当前放到第i位,关键数出现状态为s,最后一位放的是第j个关键数,0表示不放

枚举最后一位放什么即可,如果上一位和这一位都是关键数则需要检查gcd,其他情况直接转移即可

code

T3 战场模拟器 (simulator)

大数据结构模拟题

对于护甲和死亡,分类讨论,如果当前区间有护甲/死亡人数就要递归到叶子,否则就是普通的区间修改,需要写两个函数,kill专门递归到叶子,attack/就只是普通修改,然后每次分左右区间都要分讨一下来决定调用什么函数,以此减小复杂度

code

T4 点亮 (light)

60ptscode

2024.10.19

暴力不挂好心情~

由于是后期补的,没太多时间写,所以扔篇大题解

T1 排列最小生成树

暴力50,正解使用根号分治,每个点只需要建n条边

T2 卡牌游戏 (cardgame)

A摞到B上面发现 ji(modg),g=gcd(n,m)Bj都会和Ai对对碰,所以分别存储,二分找界限统计长度即可

code

T3 比特跳跃 (jump)

就按照题解说的模拟就行了

69pts,按位或的包没过

T4 区间 (interval)

咕咕咕

2024.10.20

T1 Reverse

发现每次交换1可达的位置奇偶性相同,所以使用set分别存储奇偶数,每次lowerbound找下限可达点,然后用bfs跳,并删去被更新的点,这样就能保证每个点只被更新一次。注意迭代器的尿性

code

T2 Silhouette

先对A,B排序,并不影响答案,然后令每一格 s=min(Ai,Bj),发现相同s的个子形成矩形或者L型,使用容斥计算,具体原理

code

T3 Seat

一个结论是,对于任意一个人,他坐下时离最近的人的距离是一定的,那么可以将所有人按照坐下时的距离分成若干层。对于距离为1的人特殊处理,因为此时怎么选都是等概率的,对于其他距离的人,他们选择座位时可能会存在长度为奇数的空区间以及长度为偶数的空区间,前者有一个备选位置,后者有两个,所以需要大炮。定义dpi,j表示已经坐了i个人,还剩j个偶区间的概率,根据当前人坐在奇区间内还是偶区间内来转移

考虑到偶区间存在两个备选位置,两个位置是等价的,因此钦定一个人坐在某个位置,得到一系列答案,再对称推出选另一个位置的答案即可

code

T4 万猪拱塔

咕咕咕

2024.10.21

看到大家都不会做就放心了

T2没判误解挂了20 QwQ

T1 岛屿

怎么说呢。。。

code

T2 最短路

考虑建立最短路树,以1为根节点。

如果把点i到它父亲的边断了,为了到达 ,我们需要一条边连接i的子树内任意一节点和子树外任意一节点

这样需要枚举非树边,为了减少时间复杂度,不妨考虑一条非树边的贡献

如图,对于非树边(u,v),可以转化为depu+depv+w(u,v)depk,前三者都是定的,只有后者动,所以跳祖先更新ans,可以使用并查集优化 但这题暴力跳父亲也能过

code

T3 列表

第一个性质可以导出第二个性质

定义双指针 L,R 为出现的连续数字(即L,L+1...RS内出现),然后用性质2单调移动指针

根据性质2的等价转换(区间内至少有RL+1(ni)个数),可得numRL+1(ni)

这里有个巧妙的转化:对于一个位置,枚举到它时的i是一定的,所以一个位置的ni是固定的,可以建树时设好。那么移动指针的时候维护num即可,比如R右移一位,然后R的贡献就是给[1,posR] + 1,这个区间是posR<N+1的区间,>N+1时应该是[posR,2N+1],但是[N+1i,N+1+i]是对称的,又因为一个数最多产生一个贡献,所以区间折叠,这样不管L,R怎么变修改区间都是[1,pos]

那么每跳一次R,用非法情况跳L,即存在一个位置的值不满足大于等于的关系,那么如果最小值都满足就合法了

code

T4 种植

对偶图的意思就是说新建一个图(此题中新图似乎还不是对偶图,那玩意儿是最小割用的,这里只是单纯沿用定义),新图的边与旧图的边恰好有一个交点,对应题目中的每条路径上恰好一株农作物

35pts的数据告诉我们,没障碍时左下到右上的对角线条数就是答案。我们可以由此扩展,建出由该方向对角线组成的图,就是所谓的对偶图,然后用这个图求答案。此题中的性质就是新图中左下角到右上角的路径数就是答案

考虑怎么处理障碍物。对角线肯定是沿着空地延伸的,当遇到障碍时,需要跳到障碍旁边的空地以继续延伸,所以将障碍周围的三个格子合并入他自己,就是所谓的四联通块缩点,然后直接对缩的点和空地连边即可

求路径数用拓扑序就行了

code

2024.10.22

简单签到+暴力乱c

T1 冒泡排序

就是对 mod k同余的排序了,分组排序再输出即可

code

T2 染色

暴力完全写不出来

就是把整个区间分成若干个色段,分成i个色段有fi种方法,这i个色段的分布有Cn1i1

bitset优化:用异或模拟减去dpc,然后右移,因为多加了一个字符,最后或一个2模拟加一

code

T4 山峦(mountain)

数据范围注定这题很暴力,搜索都有35

考虑到一行填数方案最多46280 (首项为10),所以直接把所有可能的填数状态搜出来,用hash压缩并赋予编号

dpi,S,w表示第i行填数方案为S,总和为w的方案数

原始的方法是枚举相邻行check后转移,优化是按照S的字典序做前缀和,这里的前缀和分为两步:首先找到上一行状态的后继S,将dp汇入。其次是行内前缀和,因为行内递减也有答案的累积,所以还要预处理首项相同时各方案的前缀关系以进行前缀和

更多细节见代码,第18个点卡常,一堆人上火车头干过去的...

T3

标程23k..............古神题............

感受一下威压
#include <cstdio>
#include <map>
#include <iostream>
#include <algorithm>
#include <bitset>
#include <queue>
#include <stack>
#include <vector>
#include <random>
#include <cstring>
#include <ctime>
#include <cmath>
#include <assert.h>
#include <unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define LL long long
#define pp pair<LL, LL>
#define mp make_pair
#define ull unsigned long long
namespace IO {
const int sz = 1 << 22;
char a[sz + 5], b[sz + 5], *p1 = a, *p2 = a, *t = b, p[105];
inline char gc() {
    //	return p1==p2?(p2=(p1=a)+fread(a,1,sz,stdin),p1==p2?EOF:*p1++):*p1++;
    return getchar();
}
template <class T>
void gi(T& x) {
    x = 0;
    int f = 1;
    char c = gc();
    if (c == '-')
        f = -1;
    for (; c < '0' || c > '9'; c = gc())
        if (c == '-')
            f = -1;
    for (; c >= '0' && c <= '9'; c = gc()) x = x * 10 + (c - '0');
    x = x * f;
}
inline void flush() { fwrite(b, 1, t - b, stdout), t = b; }
inline void pc(char x) {
    *t++ = x;
    if (t - b == sz)
        flush();
}
template <class T>
void pi(T x, char c = '\n') {
    if (x < 0)
        pc('-'), x = -x;
    if (x == 0)
        pc('0');
    int t = 0;
    for (; x; x /= 10) p[++t] = x % 10 + '0';
    for (; t; --t) pc(p[t]);
    pc(c);
}
struct F {
    ~F() { flush(); }
} f;
}  // namespace IO
using IO::gi;
using IO::pc;
using IO::pi;
const int mod = 1e9 + 7;
inline int add(int x, int y) { return x + y >= mod ? x + y - mod : x + y; }
inline int dec(int x, int y) { return x - y < 0 ? x - y + mod : x - y; }
inline int mul(int x, int y) { return 1ll * x * y % mod; }
inline int qkpow(int a, int b) {
    if (b < 0)
        return 0;
    int ans = 1, base = a % mod;
    while (b) {
        if (b & 1)
            ans = 1ll * ans * base % mod;
        base = 1ll * base * base % mod;
        b >>= 1;
    }
    return ans;
}
int fac[1000005], inv[1000005], Invn[600005];
inline int binom(int n, int m) {
    if (n < m || m < 0)
        return 0;
    return 1ll * fac[n] * inv[m] % mod * inv[n - m] % mod;
}
void init_C(int n) {
    fac[0] = 1;
    for (int i = 1; i <= n; i++) fac[i] = 1ll * fac[i - 1] * i % mod;
    inv[0] = 1;
    inv[n] = qkpow(fac[n], mod - 2);
    for (int i = n - 1; i >= 1; i--) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
    Invn[0] = Invn[1] = 1;
    for (int i = 1; i <= 200000; i++) Invn[i] = (LL)(mod - mod / i) * Invn[mod % i] % mod;
}
const LL INF = 1e18;
struct node3 {
    pp mi1, mi2;
    inline void init() { mi1 = mi2 = pp(INF, 0); }
} g1[100005], g2[100005], wg1[100005], wg2[100005];
inline void Add(node3& w1, pp w2) {
    if (!w2.second)
        return;
    if (w1.mi1.second == w2.second)
        w1.mi1.first = min(w1.mi1.first, w2.first);
    else if (w1.mi2.second == w2.second) {
        w1.mi2.first = min(w1.mi2.first, w2.first);
        if (w1.mi1.first > w1.mi2.first)
            swap(w1.mi1, w1.mi2);
    } else {
        if (w2.first < w1.mi1.first)
            w1.mi2 = w1.mi1, w1.mi1 = w2;
        else if (w2.first < w1.mi2.first)
            w1.mi2 = w2;
    }
}
int Log[100005];
struct ST_min {
    node3 f[100005][21];
    inline node3 query(int l, int r) {
        node3 res;
        res.init();
        if (l > r)
            return res;
        int k = Log[r - l + 1];
        res = f[r - (1 << k) + 1][k];
        Add(res, f[l][k].mi1);
        Add(res, f[l][k].mi2);
        return res;
    }
    inline void init(int N) {
        for (int j = 1; (1 << j) <= N; j++)
            for (int i = 1; i + (1 << j) - 1 <= N; i++) {
                f[i][j] = f[i + (1 << (j - 1))][j - 1];
                Add(f[i][j], f[i][j - 1].mi1);
                Add(f[i][j], f[i][j - 1].mi2);
            }
    }
} T1[2], T2[2];
int son1[100005], son2[100005], dep11[100005], dep22[100005], seg1[100005], seg2[100005], rev11[100005],
    rev22[100005];
int top1[100005], top2[100005];
int n, fa[200005], id1[100005], id2[100005], cnt1, cnt2, dfn1[100005], dfn2[100005];
int rev1[100005], rev2[100005], f2[100005][21], sz1[100005], sz2[100005], f1[100005][21];
int st1[100005][21], st2[100005][21];
LL jp1[100005][21], jp2[100005][21];
LL dep1[100005], dep2[100005];
pp mn[200005];
struct node {
    int to, w;
};
vector<node> G1[100005], G2[100005];
inline int findSet(int u) { return fa[u] == u ? u : fa[u] = findSet(fa[u]); }
inline int Min1(int u, int v) { return dfn1[u] < dfn1[v] ? u : v; }
inline int Min2(int u, int v) { return dfn2[u] < dfn2[v] ? u : v; }
inline int LCA1(int u, int v) {
    if (u == v)
        return u;
    if ((u = dfn1[u]) > (v = dfn1[v]))
        swap(u, v);
    int k = Log[v - u++];
    return Min1(f1[u][k], f1[v - (1 << k) + 1][k]);
}
inline int LCA2(int u, int v) {
    if (u == v)
        return u;
    if ((u = dfn2[u]) > (v = dfn2[v]))
        swap(u, v);
    int k = Log[v - u++];
    return Min2(f2[u][k], f2[v - (1 << k) + 1][k]);
}
inline LL getdis(int op, int u, int v) {
    if (op == 1)
        return dep1[u] + dep1[v] - 2 * dep1[LCA1(u, v)];
    else
        return dep2[u] + dep2[v] - 2 * dep2[LCA2(u, v)];
}
inline void dfs1(int u, int ff) {
    dep11[u] = dep11[ff] + 1;
    f1[dfn1[u] = ++cnt1][0] = ff;
    rev1[cnt1] = u;
    sz1[u] = 1;
    for (int i = 1; i <= 20; i++)
        st1[u][i] = st1[st1[u][i - 1]][i - 1], jp1[u][i] = jp1[u][i - 1] + jp1[st1[u][i - 1]][i - 1];
    for (auto to : G1[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        dep1[v] = dep1[u] + w;
        st1[v][0] = u, jp1[v][0] = w;
        dfs1(v, u);
        sz1[u] += sz1[v];
        if (sz1[v] > sz1[son1[u]])
            son1[u] = v;
    }
}
inline void dfs11(int u, int ff) {
    if (son1[u]) {
        seg1[son1[u]] = ++seg1[0];
        top1[son1[u]] = top1[u];
        rev11[seg1[0]] = son1[u];
        dfs11(son1[u], u);
    }
    for (auto to : G1[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        if (!top1[v]) {
            seg1[v] = ++seg1[0];
            top1[v] = v;
            rev11[seg1[0]] = v;
            dfs11(v, u);
        }
    }
}
inline void dfs2(int u, int ff) {
    dep22[u] = dep22[ff] + 1;
    f2[dfn2[u] = ++cnt2][0] = ff;
    rev2[cnt2] = u;
    sz2[u] = 1;
    for (int i = 1; i <= 20; i++)
        st2[u][i] = st2[st2[u][i - 1]][i - 1], jp2[u][i] = jp2[u][i - 1] + jp2[st2[u][i - 1]][i - 1];
    for (auto to : G2[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        dep2[v] = dep2[u] + w;
        st2[v][0] = u, jp2[v][0] = w;
        dfs2(v, u);
        sz2[u] += sz2[v];
        if (sz2[v] > sz2[son2[u]])
            son2[u] = v;
    }
}
inline void dfs22(int u, int ff) {
    if (son2[u]) {
        seg2[son2[u]] = ++seg2[0];
        top2[son2[u]] = top2[u];
        rev22[seg2[0]] = son2[u];
        dfs22(son2[u], u);
    }
    for (auto to : G2[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        if (!top2[v]) {
            seg2[v] = ++seg2[0];
            top2[v] = v;
            rev22[seg2[0]] = v;
            dfs22(v, u);
        }
    }
}
struct node2 {
    pp u, v;
} t[400005], po1[100005], po2[100005];
LL tag[400005];
#define ls(u) u << 1
#define rs(u) u << 1 | 1
inline node2 merge(int op, node2 A, node2 B) {
    node2 tmp;
    LL res = -1;
    LL d1 =
        (A.u.first == A.v.first ? A.u.second : A.u.second + A.v.second) + getdis(op, A.u.first, A.v.first);
    LL d2 =
        (B.u.first == B.v.first ? B.u.second : B.u.second + B.v.second) + getdis(op, B.u.first, B.v.first);
    LL d3 =
        (A.u.first == B.v.first ? A.u.second : A.u.second + B.v.second) + getdis(op, A.u.first, B.v.first);
    LL d4 =
        (B.u.first == A.v.first ? B.u.second : B.u.second + A.v.second) + getdis(op, B.u.first, A.v.first);
    LL d5 =
        (A.u.first == B.u.first ? A.u.second : A.u.second + B.u.second) + getdis(op, A.u.first, B.u.first);
    LL d6 =
        (A.v.first == B.v.first ? A.v.second : A.v.second + B.v.second) + getdis(op, A.v.first, B.v.first);
    res = max(d1, d2), res = max(res, max(d3, d4)), res = max(res, max(d5, d6));
    if (d1 == res)
        tmp = node2{ A.u, A.v };
    if (d2 == res)
        tmp = node2{ B.u, B.v };
    if (d3 == res)
        tmp = node2{ A.u, B.v };
    if (d4 == res)
        tmp = node2{ B.u, A.v };
    if (d5 == res)
        tmp = node2{ A.u, B.u };
    if (d6 == res)
        tmp = node2{ A.v, B.v };
    return tmp;
}
inline void push_down(int u) {
    if (tag[u]) {
        tag[ls(u)] += tag[u];
        tag[rs(u)] += tag[u];
        t[ls(u)].u.second += tag[u];
        t[ls(u)].v.second += tag[u];
        t[rs(u)].u.second += tag[u];
        t[rs(u)].v.second += tag[u];
        tag[u] = 0;
    }
}
inline void updata(int op, int p, int l, int r, int L, int R, int w) {
    if (L > R)
        return;
    if (L <= l && r <= R) {
        tag[p] += w;
        t[p].u.second += w;
        t[p].v.second += w;
        return;
    }
    push_down(p);
    int mid = (l + r) >> 1;
    if (L <= mid)
        updata(op, ls(p), l, mid, L, R, w);
    if (mid + 1 <= R)
        updata(op, rs(p), mid + 1, r, L, R, w);
    t[p] = merge(op, t[ls(p)], t[rs(p)]);
}
inline void build(int op, int p, int l, int r) {
    tag[p] = 0;
    if (l == r) {
        if (op == 2)
            t[p].u = t[p].v = pp(rev1[l], dep1[rev1[l]]);
        else
            t[p].u = t[p].v = pp(rev2[l], dep2[rev2[l]]);
        return;
    }
    int mid = (l + r) >> 1;
    build(op, ls(p), l, mid);
    build(op, rs(p), mid + 1, r);
    t[p] = merge(op, t[ls(p)], t[rs(p)]);
}
inline void redfs1(int u, int ff) {
    po1[u] = t[1];
    for (auto to : G1[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        updata(2, 1, 1, n, dfn1[v], dfn1[v] + sz1[v] - 1, -w);
        updata(2, 1, 1, n, 1, dfn1[v] - 1, w);
        updata(2, 1, 1, n, dfn1[v] + sz1[v], n, w);
        redfs1(v, u);
        updata(2, 1, 1, n, dfn1[v], dfn1[v] + sz1[v] - 1, w);
        updata(2, 1, 1, n, 1, dfn1[v] - 1, -w);
        updata(2, 1, 1, n, dfn1[v] + sz1[v], n, -w);
    }
}
inline void redfs2(int u, int ff) {
    po2[u] = t[1];
    for (auto to : G2[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        updata(1, 1, 1, n, dfn2[v], dfn2[v] + sz2[v] - 1, -w);
        updata(1, 1, 1, n, 1, dfn2[v] - 1, w);
        updata(1, 1, 1, n, dfn2[v] + sz2[v], n, w);
        redfs2(v, u);
        updata(1, 1, 1, n, dfn2[v], dfn2[v] + sz2[v] - 1, w);
        updata(1, 1, 1, n, 1, dfn2[v] - 1, -w);
        updata(1, 1, 1, n, dfn2[v] + sz2[v], n, -w);
    }
}
inline void dfss1(int u, int ff) {
    g1[u].init();
    wg1[u].init();
    Add(g1[u], pp(0, id1[u]));
    for (auto to : G1[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        dfss1(v, u);
        Add(g1[u], pp(g1[v].mi1.first + w, g1[v].mi1.second));
        Add(g1[u], pp(g1[v].mi2.first + w, g1[v].mi2.second));
    }
}
inline void redfss1(int u, int ff) {
    node3 pre;
    pre.init();
    Add(wg1[u], pp(0, id1[u]));
    for (auto to : G1[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        Add(wg1[v], pp(wg1[u].mi1.first + w, wg1[u].mi1.second));
        Add(wg1[v], pp(wg1[u].mi2.first + w, wg1[u].mi2.second));
        Add(wg1[v], pp(pre.mi1.first + w, pre.mi1.second));
        Add(wg1[v], pp(pre.mi2.first + w, pre.mi2.second));
        Add(pre, pp(g1[v].mi1.first + w, g1[v].mi1.second));
        Add(pre, pp(g1[v].mi2.first + w, g1[v].mi2.second));
    }
    reverse(G1[u].begin(), G1[u].end());
    pre.init();
    for (auto to : G1[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        Add(wg1[v], pp(pre.mi1.first + w, pre.mi1.second));
        Add(wg1[v], pp(pre.mi2.first + w, pre.mi2.second));
        Add(pre, pp(g1[v].mi1.first + w, g1[v].mi1.second));
        Add(pre, pp(g1[v].mi2.first + w, g1[v].mi2.second));
    }
    reverse(G1[u].begin(), G1[u].end());
    for (auto to : G1[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        redfss1(v, u);
    }
}
inline void dfss2(int u, int ff) {
    g2[u].init();
    wg2[u].init();
    Add(g2[u], pp(0, id2[u]));
    for (auto to : G2[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        dfss2(v, u);
        Add(g2[u], pp(g2[v].mi1.first + w, g2[v].mi1.second));
        Add(g2[u], pp(g2[v].mi2.first + w, g2[v].mi2.second));
    }
}
inline void redfss2(int u, int ff) {
    node3 pre;
    pre.init();
    Add(wg2[u], pp(0, id2[u]));
    for (auto to : G2[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        Add(wg2[v], pp(wg2[u].mi1.first + w, wg2[u].mi1.second));
        Add(wg2[v], pp(wg2[u].mi2.first + w, wg2[u].mi2.second));
        Add(wg2[v], pp(pre.mi1.first + w, pre.mi1.second));
        Add(wg2[v], pp(pre.mi2.first + w, pre.mi2.second));
        Add(pre, pp(g2[v].mi1.first + w, g2[v].mi1.second));
        Add(pre, pp(g2[v].mi2.first + w, g2[v].mi2.second));
    }
    reverse(G2[u].begin(), G2[u].end());
    pre.init();
    for (auto to : G2[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        Add(wg2[v], pp(pre.mi1.first + w, pre.mi1.second));
        Add(wg2[v], pp(pre.mi2.first + w, pre.mi2.second));
        Add(pre, pp(g2[v].mi1.first + w, g2[v].mi1.second));
        Add(pre, pp(g2[v].mi2.first + w, g2[v].mi2.second));
    }
    reverse(G2[u].begin(), G2[u].end());
    for (auto to : G2[u]) {
        int v = to.to, w = to.w;
        if (v == ff)
            continue;
        redfss2(v, u);
    }
}
inline node3 query22(int op, int u, int v, LL ex) {
    int fu = top2[u], fv = top2[v];
    node3 res;
    res.init();
    while (fu != fv) {
        if (dep22[fu] >= dep22[fv]) {
            node3 tmp = T2[op].query(seg2[fu], seg2[u]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
            u = st2[fu][0];
        } else {
            node3 tmp = T2[op].query(seg2[fv], seg2[v]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
            v = st2[fv][0];
        }
        fu = top2[u], fv = top2[v];
    }
    if (dep22[u] > dep22[v])
        swap(u, v);
    node3 tmp = T2[op].query(seg2[u], seg2[v]);
    Add(res, tmp.mi1), Add(res, tmp.mi2);
    return node3{ pp(res.mi1.first + ex, res.mi1.second), pp(res.mi2.first + ex, res.mi2.second) };
}
inline pp query2(int u, int v, LL w1, LL w2, int c) {  //锟斤拷色锟斤拷锟斤拷锟斤拷 c
    int lca = LCA2(u, v);
    //	if(lca!=1)cerr<<lca<<" "<<"FUCK"<<endl;
    int to = u;
    LL sum = w1, tot = getdis(2, u, v) + w1 + w2;
    node3 res, tmp;
    res.init();
    LL ex = max(getdis(2, u, lca) + w1, getdis(2, v, lca) + w2);
    Add(res, pp(wg2[lca].mi1.first + ex, wg2[lca].mi1.second));
    Add(res, pp(wg2[lca].mi2.first + ex, wg2[lca].mi2.second));
    if (w1 >= tot - w1) {
        node3 tmp;
        tmp = query22(1, u, lca, w1 + dep2[u]);
        Add(res, tmp.mi1), Add(res, tmp.mi2);
    } else {
        for (int i = 20; i >= 0; i--) {
            if (sum + jp2[to][i] <= tot - sum - jp2[to][i]) {
                sum += jp2[to][i];
                to = st2[to][i];
            }
        }
        node3 tmp;
        if (dep22[to] <= dep22[lca]) {  //全锟斤拷锟斤拷 v 锟斤拷
            tmp = query22(0, u, lca, w2 + dep2[v] - 2 * dep2[lca]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
        } else {
            tmp = query22(0, u, to, w2 + dep2[v] - 2 * dep2[lca]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
            tmp = query22(1, st2[to][0], lca, w1 + dep2[u]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
        }
    }
    to = v;
    sum = w2;
    if (w2 >= tot - w2) {
        tmp = query22(1, v, lca, w2 + dep2[v]);
        Add(res, tmp.mi1), Add(res, tmp.mi2);
    } else {
        for (int i = 20; i >= 0; i--) {
            if (sum + jp2[to][i] <= tot - sum - jp2[to][i]) {
                sum += jp2[to][i];
                to = st2[to][i];
            }
        }
        if (dep22[to] <= dep22[lca]) {  //全锟斤拷锟斤拷 u 锟斤拷
            tmp = query22(0, v, lca, w1 + dep2[u] - 2 * dep2[lca]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
        } else {
            tmp = query22(0, v, to, w1 + dep2[u] - 2 * dep2[lca]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
            tmp = query22(1, st2[to][0], lca, w2 + dep2[v]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
        }
    }
    if (res.mi1.second == c)
        return res.mi2;
    return res.mi1;
}
inline node3 query11(int op, int u, int v, LL ex) {
    int fu = top1[u], fv = top1[v];
    node3 res;
    res.init();
    while (fu != fv) {
        if (dep11[fu] >= dep11[fv]) {
            node3 tmp = T1[op].query(seg1[fu], seg1[u]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
            u = st1[fu][0];
        } else {
            node3 tmp = T1[op].query(seg1[fv], seg1[v]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
            v = st1[fv][0];
        }
        fu = top1[u], fv = top1[v];
    }
    if (dep11[u] > dep11[v])
        swap(u, v);
    node3 tmp = T1[op].query(seg1[u], seg1[v]);
    Add(res, tmp.mi1), Add(res, tmp.mi2);
    return node3{ pp(res.mi1.first + ex, res.mi1.second), pp(res.mi2.first + ex, res.mi2.second) };
}
inline pp query1(int u, int v, LL w1, LL w2, int c) {  //锟斤拷色锟斤拷锟斤拷锟斤拷 c
    int lca = LCA1(u, v);
    //	if(lca!=1)cerr<<lca<<" "<<"FUCK"<<endl;
    int to = u;
    LL sum = w1, tot = getdis(1, u, v) + w1 + w2;
    node3 res, tmp;
    res.init();
    LL ex = max(getdis(1, u, lca) + w1, getdis(1, v, lca) + w2);
    Add(res, pp(wg1[lca].mi1.first + ex, wg1[lca].mi1.second));
    Add(res, pp(wg1[lca].mi2.first + ex, wg1[lca].mi2.second));
    if (w1 >= tot - w1) {
        tmp = query11(1, u, lca, w1 + dep1[u]);
        Add(res, tmp.mi1), Add(res, tmp.mi2);
    } else {
        for (int i = 20; i >= 0; i--) {
            if (sum + jp1[to][i] <= tot - sum - jp1[to][i]) {
                sum += jp1[to][i];
                to = st1[to][i];
            }
        }
        node3 tmp;
        if (dep11[to] <= dep11[lca]) {  //全锟斤拷锟斤拷 v 锟斤拷
            tmp = query11(0, u, lca, w2 + dep1[v] - 2 * dep1[lca]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
        } else {
            tmp = query11(0, u, to, w2 + dep1[v] - 2 * dep1[lca]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
            tmp = query11(1, st1[to][0], lca, w1 + dep1[u]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
        }
    }
    to = v;
    sum = w2;
    if (w2 >= tot - w2) {
        node3 tmp;
        tmp = query11(1, v, lca, w2 + dep1[v]);
        Add(res, tmp.mi1), Add(res, tmp.mi2);
    } else {
        for (int i = 20; i >= 0; i--) {
            if (sum + jp1[to][i] <= tot - sum - jp1[to][i]) {
                sum += jp1[to][i];
                to = st1[to][i];
            }
        }
        if (dep11[to] <= dep11[lca]) {  //全锟斤拷锟斤拷 u 锟斤拷
            tmp = query11(0, v, lca, w1 + dep1[u] - 2 * dep1[lca]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
        } else {
            tmp = query11(0, v, to, w1 + dep1[u] - 2 * dep1[lca]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
            tmp = query11(1, st1[to][0], lca, w2 + dep1[v]);
            Add(res, tmp.mi1), Add(res, tmp.mi2);
        }
    }
    if (res.mi1.second == c)
        return res.mi2;
    return res.mi1;
}
inline void solve() {
    for (int i = 2; i <= 100000; i++) Log[i] = Log[i >> 1] + 1;
    gi(n);
    for (int i = 1; i < n; i++) {
        int u, v, w;
        gi(u), gi(v), gi(w);
        G1[u].push_back(node{ v, w });
        G1[v].push_back(node{ u, w });
    }
    for (int i = 1; i < n; i++) {
        int u, v, w;
        gi(u), gi(v), gi(w);
        G2[u].push_back(node{ v, w });
        G2[v].push_back(node{ u, w });
    }
    seg1[0] = seg1[1] = top1[1] = rev11[1] = 1;
    seg2[0] = seg2[1] = top2[1] = rev22[1] = 1;
    dfs1(1, 0), dfs2(1, 0), dfs11(1, 0), dfs22(1, 0);
    for (int j = 1; (1 << j) <= cnt1; j++)
        for (int i = 1; i + (1 << j) - 1 <= cnt1; i++)
            f1[i][j] = Min1(f1[i][j - 1], f1[i + (1 << (j - 1))][j - 1]);
    for (int j = 1; (1 << j) <= cnt2; j++)
        for (int i = 1; i + (1 << j) - 1 <= cnt2; i++)
            f2[i][j] = Min2(f2[i][j - 1], f2[i + (1 << (j - 1))][j - 1]);
    build(2, 1, 1, n);
    redfs1(1, 0);
    build(1, 1, 1, n);
    redfs2(1, 0);
    for (int i = 1; i <= 2 * n; i++) fa[i] = i;
    int cnt = 2 * n;
    LL ans = 0;
    while (cnt > 1) {
        for (int i = 1; i <= n; i++) id1[i] = findSet(i), mn[i] = pp(INF, 0);
        for (int i = 1; i <= n; i++) id2[i] = findSet(i + n), mn[i + n] = pp(INF, 0);
        dfss1(1, 0), dfss2(1, 0);
        redfss1(1, 0), redfss2(1, 0);
        for (int i = 1; i <= n; i++) {
            int u = rev11[i], v = rev22[i];
            T1[0].f[i][0].mi1 = pp(g1[u].mi1.first + dep1[u], g1[u].mi1.second);
            T1[0].f[i][0].mi2 = pp(g1[u].mi2.first + dep1[u], g1[u].mi2.second);
            T1[1].f[i][0].mi1 = pp(g1[u].mi1.first - dep1[u], g1[u].mi1.second);
            T1[1].f[i][0].mi2 = pp(g1[u].mi2.first - dep1[u], g1[u].mi2.second);

            T2[0].f[i][0].mi1 = pp(g2[v].mi1.first + dep2[v], g2[v].mi1.second);
            T2[0].f[i][0].mi2 = pp(g2[v].mi2.first + dep2[v], g2[v].mi2.second);
            T2[1].f[i][0].mi1 = pp(g2[v].mi1.first - dep2[v], g2[v].mi1.second);
            T2[1].f[i][0].mi2 = pp(g2[v].mi2.first - dep2[v], g2[v].mi2.second);
        }
        T1[0].init(n), T2[0].init(n), T1[1].init(n), T2[1].init(n);
        for (int i = 1; i <= n; i++) {
            int u = po1[i].u.first, v = po1[i].v.first;
            LL w1 = po1[i].u.second, w2 = po1[i].v.second;
            mn[id1[i]] = min(mn[id1[i]], query2(u, v, w1, w2, id1[i]));
        }
        for (int i = 1; i <= n; i++) {
            int u = po2[i].u.first, v = po2[i].v.first;
            LL w1 = po2[i].u.second, w2 = po2[i].v.second;
            mn[id2[i]] = min(mn[id2[i]], query1(u, v, w1, w2, id2[i]));
        }
        for (int i = 1; i <= 2 * n; i++) {
            if (mn[i].second) {
                int u = i, v = mn[i].second;
                u = findSet(u), v = findSet(v);
                if (u != v) {
                    fa[v] = u;
                    ans += mn[i].first;
                    cnt--;
                }
            }
        }
        //	cerr<<cnt<<endl;
    }
    pi(ans);
}
/*
要一锟斤拷锟斤拷锟斤拷
*/
signed main() {
    freopen("graph.in", "r", stdin);
    freopen("graph.out", "w", stdout);
    srand(time(0));
    solve();
    return 0;
}
/*
 */
posted @   why?123  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示