[loj2469]最小方差生成树
2018年论文题
约定:令点集V=[1,n]、边集E=[1,m],记m条边依次为e_{i}=(x_{i},y_{i},c_{i})(其中1\le i\le m),将其按照c_{i}从小到大排序,即不妨假设有c_{1}\le c_{2}\le...\le c_{m}
先来考虑T=1的情况,即如何求最小方差生成树
题意即求\min_{E_{T}\subseteq E,E_{T}为生成树}\frac{\sum_{x\in E_{T}}(\mu-c_{x})^{2}}{n-1}(其中\mu=\frac{\sum_{x\in E_{T}}c_{x}}{n-1})
考虑函数f(x)=\frac{\sum_{i=1}^{n-1}(x-a_{i})^{2}}{n-1},根据二次函数的性质其最小值恰在x=\frac{\sum_{i=1}^{n-1}a_{i}}{n-1}处取到
换言之,有\frac{\sum_{x\in E_{T}}(\mu-c_{x})^{2}}{n-1}=\min_{\mu\in R}\frac{\sum_{x\in E_{T}}(\mu-c_{x})^{2}}{n-1}
代入后交换顺序,即\min_{\mu\in R}\frac{\min_{E_{T}\subseteq E,E_{T}为生成树}\sum_{x\in E_{T}}(\mu-c_{x})^{2}}{n-1},其中分子即以(\mu-c_{i})^{2}为边权求最小生成树
令E_{\chi}表示\mu=\chi时最小生成树的边集,为了使其能被唯一确定,求最小生成树时将e_{i}按照(\mu-c_{i})^{2}和i这两个关键字从小到大排序(假设用kruskal求最小生成树)
将问题从边的角度来考虑,显然i\in E_{\chi}当且仅当\mu=\chi时排在e_{i}前面的边不能使x_{i}和y_{i}连通
不妨假设\chi \le c_{i},那么e_{j}排在e_{i}前面当且仅当2\chi-c_{i}\le c_{j}<c_{i}或c_{j}=c_{i}且j<i
显然\chi的范围具有单调性,即只需要不断加入e_{i-1},e_{i-2},...直至x_{i}和y_{i}连通,设最后一条边加入的是e_{k},那么满足\chi\le c_{i}且i\in E_{\chi}的\chi的范围为\frac{c_{i}+c_{k}}{2}<\chi\le c_{i}
(特别的,若最后仍未连通即令c_{k}=-\infty)
显然,使用LCT维护i之前的边(不包括i)关于编号的最大生成树,询问的也即该生成树从x_{i}到y_{i}路径上的编号最小的边,时间复杂度为o(m\log m)
关于\chi>c_{i}且i\in E_{\chi}的范围,可以类似地求出,但会多一个2的常数,实际上可以避免
记l_{i}为最大的k满足e[k,i)能使x_{i}和y_{i}连通,r_{i}为最小的k满足e(i,k]能使x_{i}和y_{i}连通
结论:若L_{i}存在,则R_{L_{i}}=i;若R_{i}存在,则R_{L_{i}}=i
记k=L_{i},则e[k,i)能使x_{i}和y_{i}连通,那么e(k,i]即能使x_{k}和y_{k}连通,也即R_{k}\le i
另一方面,如果e(k,i)就能使x_{k}和y_{k}连通,那么e[k,i)与e(k,i)的连通性应该相同(因为(x_{k},y_{k})不影响连通性),也即l_{i}可以为k+1,与L_{i}的最大性矛盾,因此R_{k}\ge i
综上,即有R_{k}=i,类似地也可以得到后者
由此即可线性求出R_{i}(L_{i}之前已求出),根据后半部分,未被覆盖的R_{i}即为无解
进而将两个范围求并,即得到满足i\in E_{\chi}的\chi的范围为(\frac{c_{L_{i}}+c_{i}}{2},\frac{c_{i}+c_{R_{i}}}{2}]
此时,E_{\chi}即对应范围包含\chi的i所组成的集合(注意这个范围是充分必要的),那么只需要通过离散和差分对每一个位置维护S_{1}=\sum c_{i}和S_{2}=\sum c^{2}_{i}的和即可(方差即\frac{(n-1)S_{2}-S_{1}^{2}}{(n-1)^{2}})
另外,需要考虑实数的位置如何处理,可以将权值乘2并用两整数中间的部分代替该段实数
时间复杂度为o(m\log m),可以通过
下面考虑T=2的情况,即如何对删去每一条边后的图求最小方差生成树
通过T=1时的做法,即可在o(m\log m)的时间内求出最小方差生成树即其方案
显然删除方案以外的边是不影响答案的,因此只需要考虑方案中的n-1条边,那么对这n-1条边暴力删除并再求一次最小方差生成树,即得到一个o(nm\log m)的做法,但无法通过
假设删除的边是e_{del},那么L_{i}发生变化的边必然都在e(del,m]这些边关于编号的最小生成树上,因为如果e_{i}不在最小生成树上,即等价于e(del,i)能使x_{i}和y_{i}连通,显然删去e_{del}没有意义
显然这样的边只有o(n)条,但求最大生成树仍要从前往后依次加边,复杂度并没有优化
记T_{1}为e[1,del)的关于编号的最大生成树,T_{2}为e(del,m]的关于编号的最小生成树
初始令T=T_{2},并将T_{1}中的边的按编号从大到小依次加入T,并继续维护T为最小生成树
结论:假设在加入e_{i}时删除了e_{j},则有L_{j}=i
显然x_{j}到y_{j}路径上所有边编号都在[i,j)中,因此也即L_{j}\ge i
同时如果L_{j}>i,那么不难得到x_{i}和y_{i}可以通过e(i,del)连通,与e_{i}在T_{1}上矛盾
通俗的来说,求e[1,i)的最大生成树上在e_{del}之前的边一定在e[1,del)的最大生成树上,并且e_{del}之后的边一定不会作为l_{i},因此只关心于这类边的连通性
另外,对于T_{1}中最终仍没有被删除的边e_{i},则L_{i}无解
此时,重新计算L_{i}和R_{i}的时间复杂度即降为o(n^{2}\log m)
下面,给出一些关于实现上的细节:
1.关于LCT的清空,可以维护一个当前的边集(用标记数组即可),那么清空时遍历所有边并用删掉即可,由于删除的复杂度与加入时相同,因此相当于仅为o(m),总复杂度也即o(nm)
2.关于T_{1}和T_{2}需要在初始预处理,在求最小/最大生成树过程中,当访问到的边是在方案中时,就将当前LCT中维护的边集o(m)找出即可,总复杂度也为o(nm)
3.关于离散和差分,重新暴力排序+二分复杂度又会退化为o(nm\log m),注意到总共只会额外产生o(n^{2})个位置,将这些位置预处理出来并排序,然后将初始的差分数组记录
此时,每一次即对差分数组的o(n)个位置修改,总复杂度也即o(m\log m+n^{2}\log m+nm)
时间复杂度为o(m\log m+n^{2}\log m+nm),可以通过
然而,注意到答案的范围为n^{2}C^{2},而在子任务8该值达到了10^{41}的级别,无法使用__int128存储
由此,即需要在差分的过程中使用高精度乘法求S_{1}^{2}(显然其他都不需要高精度),设高精度的常数为o(P),时间复杂度即变为o(m\log n+n^{2}\log m+Pnm),无法通过
下面,具体的来描述差分的过程——
令N=n^{2}+m,差分数组即是两个长度为N的序列,初始为分别为\Delta S_{1}(i)和\Delta S_{2}(i)(下标为[1,N])
每一次查询,修改其中o(n)个位置的值(无后效性),并查询
\min_{1\le i\le N}\left((n-1)\sum_{j=1}^{i}\Delta S_{2}(j)-(\sum_{j=1}^{i}\Delta S_{1}(i))^{2}\right)
(其余部分的复杂度显然都可以做到o(m\log m+n^{2}\log m+nm+Pn^{2}),其中o(Pn^{2})为计算修改的值)
预处理出前缀和S_{1}(i)=\sum_{j=1}^{i}\Delta S_{1}(j),S_{2}(i)=\sum_{j=1}^{i}\Delta S_{2}(j)(对于初始状态),每一次修改的o(n)个位置即将原序列划分为o(n)段,并对每一段[l,r]分别求出i\in [l,r]的最小值
(其中[l,r]不包含修改的位置,修改的位置直接暴力o(Pn^{2})计算即可)
对于[l,r],求出此次修改对i\in [l,r]的S_{1}(i)和S_{2}(i)的变化量,分别记作\Delta s_{1}和\Delta s_{2}(显然对所有位置都相同),那么i\in [l,r]的最小值即
\min_{i=l}^{r}\left((n-1)(S_{2}(i)+\Delta s_{2})-(S_{1}(i)+\Delta s_{1})^{2}\right)
并对于其中一段[l,r],求出其之前的本次修改的变化量\Delta s_{1}和\Delta s_{2}
简单化简,即
\min_{i=l}^{r}\left(-2\Delta s_{1}S_{1}(i)+((n-1)S_{2}(i)-S_{1}^{2}(i))\right)+\left((n-1)\Delta s_{2}-\Delta s_{1}^{2}\right)
此时,问题即可以看作求经过(2S_{1}(i),(n-1)S_{2}(i)-S_{1}^{2}(i))且斜率为-\Delta s_{1}的直线的最小截距
求出[l,r]中的点所构成的下凸壳,二分找到其中第一个斜率大于等于-\Delta s_{1}的线段的左端点即为最小值
可以使用线段树来维护,预处理时先将所有点按照x坐标排序,并依次加入线段树上区间包含其的o(\log N)个凸包中,那么预处理的时间复杂度即为o(PN\log N)
查询时将[l,r]划分为o(\log N)个区间,再在每一个区间对应的线段树凸包上二分,将所有最小值取\min即可,那么查询的时间复杂度为o(Pn^{2}\log^{2}N)
进一步的,可以将线段树每一个区间对应的凸包上的询问离线并排序,再利用单调性做到线性即可
关于排序,再将所有-\Delta s_{1}排序再依次加入,注意到外部仅有o(n^{2})个,因此查询复杂度降为o(Pn^{2}\log N)
时间复杂度为o(nm+PN\log N),可以通过
(代码只优化到o(m\log m+n^{2}\log m+Pnm),但已经可以通过)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 305 4 #define M 100005 5 #define base 1000000000 6 #define ll long long 7 #define pli pair<ll,int> 8 #define fi first 9 #define se second 10 struct Data{ 11 int x,y,id; 12 ll z; 13 bool operator < (const Data &k)const{ 14 return z<k.z; 15 } 16 }e[M]; 17 struct Num{ 18 int p,len; 19 ll a[5]; 20 Num(ll k=0){ 21 p=(k<0),len=0; 22 memset(a,0,sizeof(a)); 23 k=abs(k); 24 while (k){ 25 a[len++]=k%base; 26 k/=base; 27 } 28 } 29 }Check,S1,S2,ans,z1[M],z2[M],dS1[M<<1],dS2[M<<1],Ans[M]; 30 vector<int>T1[M],T2[M]; 31 vector<pli>v0,v[M]; 32 int n,m,T,q,L0[M],R0[M],L[M],R[M],vis0[M]; 33 ll Pos[M<<1]; 34 namespace IO{ 35 int num[100]; 36 ll x; 37 char c; 38 ll read(){ 39 x=0,c=getchar(); 40 while ((c<'0')||(c>'9'))c=getchar(); 41 while ((c>='0')&&(c<='9')){ 42 x=x*10+c-'0'; 43 c=getchar(); 44 } 45 return x; 46 } 47 void write(Num x,char c='\0'){ 48 if (x.p)putchar('-'); 49 for(int i=0;i<x.len;i++) 50 for(int j=0;j<9;j++){ 51 num[++num[0]]=x.a[i]%10; 52 x.a[i]/=10; 53 } 54 while ((num[0])&&(!num[num[0]]))num[0]--; 55 if (!num[0])putchar('0'); 56 while (num[0])putchar(num[num[0]--]+'0'); 57 putchar(c); 58 } 59 }; 60 namespace Calc{ 61 int cmp(Num x,Num y){ 62 if (x.len!=y.len){ 63 if (x.len<y.len)return -1; 64 return 1; 65 } 66 for(int i=x.len-1;i>=0;i--) 67 if (x.a[i]!=y.a[i]){ 68 if (x.a[i]<y.a[i])return -1; 69 return 1; 70 } 71 return 0; 72 } 73 Num min(Num x,Num y){ 74 if (cmp(x,y)<0)return x; 75 return y; 76 } 77 Num add(Num x,Num y){ 78 Num ans; 79 if (x.p==y.p){ 80 ans.p=x.p,ans.len=max(x.len,y.len); 81 for(int i=0;i<ans.len;i++){ 82 ans.a[i]+=x.a[i]+y.a[i]; 83 if (ans.a[i]>=base){ 84 ans.a[i]-=base; 85 ans.a[i+1]++; 86 } 87 } 88 if ((ans.len<5)&&(ans.a[ans.len]))ans.len++; 89 return ans; 90 } 91 if (cmp(x,y)<0)swap(x,y); 92 ans.p=x.p,ans.len=x.len; 93 for(int i=0;i<ans.len;i++){ 94 ans.a[i]+=x.a[i]-y.a[i]; 95 if (ans.a[i]<0){ 96 ans.a[i]+=base; 97 ans.a[i+1]--; 98 } 99 } 100 while ((ans.len)&&(!ans.a[ans.len-1]))ans.len--; 101 return ans; 102 } 103 Num dec(Num x,Num y){ 104 y.p^=1; 105 return add(x,y); 106 } 107 Num mul(Num x,Num y){ 108 Num ans; 109 ans.p=(x.p^y.p),ans.len=x.len+y.len-1; 110 for(int i=0;i<x.len;i++) 111 for(int j=0;j<y.len;j++){ 112 ans.a[i+j]+=x.a[i]*y.a[j]; 113 ans.a[i+j+1]+=ans.a[i+j]/base; 114 ans.a[i+j]%=base; 115 } 116 if ((ans.len<5)&&(ans.a[ans.len]))ans.len++; 117 return ans; 118 } 119 }; 120 namespace LCT{ 121 int vis[M],st[M<<1],fa[M<<1],mn[M<<1],mx[M<<1],rev[M<<1],ch[M<<1][2]; 122 int which(int k){ 123 return ch[fa[k]][1]==k; 124 } 125 bool check(int k){ 126 return ch[fa[k]][which(k)]==k; 127 } 128 void upd(int k){ 129 rev[k]^=1; 130 swap(ch[k][0],ch[k][1]); 131 } 132 void up(int k){ 133 mn[k]=min(mn[ch[k][0]],mn[ch[k][1]]); 134 mx[k]=max(mx[ch[k][0]],mx[ch[k][1]]); 135 if (k>n){ 136 mn[k]=min(mn[k],k-n); 137 mx[k]=max(mx[k],k-n); 138 } 139 } 140 void down(int k){ 141 if (rev[k]){ 142 if (ch[k][0])upd(ch[k][0]); 143 if (ch[k][1])upd(ch[k][1]); 144 rev[k]=0; 145 } 146 } 147 void rotate(int k){ 148 int f=fa[k],g=fa[f],p=which(k); 149 fa[k]=g; 150 if (check(f))ch[g][which(f)]=k; 151 fa[ch[k][p^1]]=f,ch[f][p]=ch[k][p^1]; 152 fa[f]=k,ch[k][p^1]=f; 153 up(f),up(k); 154 } 155 void splay(int k){ 156 for(int i=k;check(i);i=fa[i])st[++st[0]]=fa[i]; 157 while (st[0])down(st[st[0]--]); 158 down(k); 159 for(int i=fa[k];check(k);i=fa[k]){ 160 if (check(i)){ 161 if (which(i)==which(k))rotate(i); 162 else rotate(k); 163 } 164 rotate(k); 165 } 166 } 167 void access(int k){ 168 int lst=0; 169 while (k){ 170 splay(k); 171 ch[k][1]=lst,up(k); 172 lst=k,k=fa[k]; 173 } 174 } 175 void make_root(int k){ 176 access(k); 177 splay(k); 178 upd(k); 179 } 180 int find_root(int k){ 181 access(k); 182 splay(k); 183 while (ch[k][0]){ 184 down(k); 185 k=ch[k][0]; 186 } 187 splay(k); 188 return k; 189 } 190 void add(int x,int y){ 191 make_root(x); 192 make_root(y); 193 fa[y]=x; 194 } 195 void del(int x,int y){ 196 make_root(x); 197 access(y); 198 splay(x); 199 fa[y]=ch[x][1]=0,up(x); 200 } 201 int query_min(int x,int y){ 202 make_root(x); 203 if (find_root(y)!=x)return 0; 204 return mn[x]; 205 } 206 int query_max(int x,int y){ 207 make_root(x); 208 if (find_root(y)!=x)return 0; 209 return mx[x]; 210 } 211 int add_min(int id){ 212 int pos=query_min(e[id].y,id+n); 213 if (pos){ 214 vis[0]--,vis[pos]=0; 215 LCT::del(e[pos].y,pos+n); 216 } 217 vis[0]++,vis[id]=1; 218 LCT::add(e[id].y,id+n); 219 return pos; 220 } 221 int add_max(int id){ 222 int pos=query_max(e[id].y,id+n); 223 if (pos){ 224 vis[0]--,vis[pos]=0; 225 LCT::del(e[pos].y,pos+n); 226 } 227 vis[0]++,vis[id]=1; 228 LCT::add(e[id].y,id+n); 229 return pos; 230 } 231 void init(){ 232 mn[0]=0x3f3f3f3f,mx[0]=0; 233 for(int i=1;i<=n+m;i++){ 234 fa[i]=rev[i]=ch[i][0]=ch[i][1]=0; 235 up(i); 236 } 237 for(int i=1;i<=m;i++)add(e[i].x,i+n); 238 } 239 void clear(){ 240 for(int i=1;i<=m;i++) 241 if (vis[i]){ 242 LCT::del(e[i].y,i+n); 243 vis[0]--,vis[i]=0; 244 } 245 } 246 }; 247 void get_LR(){ 248 memset(L0,0,sizeof(L0)); 249 memset(R0,0,sizeof(R0)); 250 LCT::clear(); 251 for(int i=1;i<=m;i++){ 252 L0[i]=LCT::add_min(i); 253 if (L0[i])R0[L0[i]]=i; 254 } 255 } 256 void get_T12(){ 257 LCT::clear(); 258 for(int i=1;i<=m;i++){ 259 if (vis0[i]){ 260 for(int j=m;j;j--) 261 if (LCT::vis[j])T1[i].push_back(j); 262 } 263 LCT::add_min(i); 264 } 265 LCT::clear(); 266 for(int i=m;i;i--){ 267 if (vis0[i]){ 268 for(int j=1;j<=m;j++) 269 if (LCT::vis[j])T2[i].push_back(j); 270 } 271 LCT::add_max(i); 272 } 273 } 274 void get_v(){ 275 v0.clear(); 276 for(int i=1;i<=m;i++){ 277 if (!L0[i])v0.push_back(make_pair(0,i)); 278 else v0.push_back(make_pair((e[L0[i]].z+e[i].z<<1)+1,i)); 279 if (R0[i])v0.push_back(make_pair((e[i].z+e[R0[i]].z<<1)+1,-i)); 280 } 281 } 282 void upd_LR(int k){ 283 LCT::clear(); 284 memcpy(L,L0,sizeof(L)); 285 L[k]=k; 286 for(int i=0;i<T2[k].size();i++){ 287 L[T2[k][i]]=0; 288 LCT::add_max(T2[k][i]); 289 } 290 for(int i=0;i<T1[k].size();i++){ 291 int pos=LCT::add_max(T1[k][i]); 292 if (pos)L[pos]=T1[k][i]; 293 } 294 memset(R,0,sizeof(R)); 295 for(int i=1;i<=m;i++) 296 if (L[i])R[L[i]]=i; 297 } 298 void upd_v(int k){ 299 T1[k].push_back(k),T2[k].push_back(k); 300 for(int i=0;i<T1[k].size();i++){ 301 int pos=T1[k][i]; 302 if (R0[pos])v[k].push_back(make_pair((e[pos].z+e[R0[pos]].z<<1)+1,pos)); 303 if (R[pos]){ 304 v0.push_back(make_pair((e[pos].z+e[R[pos]].z<<1)+1,0)); 305 v[k].push_back(make_pair((e[pos].z+e[R[pos]].z<<1)+1,-pos)); 306 } 307 } 308 for(int i=0;i<T2[k].size();i++){ 309 int pos=T2[k][i]; 310 if (!L0[pos])v[k].push_back(make_pair(0,-pos)); 311 else v[k].push_back(make_pair((e[L0[pos]].z+e[pos].z<<1)+1,-pos)); 312 if (!L[pos]){ 313 v0.push_back(make_pair(0,0)); 314 v[k].push_back(make_pair(0,pos)); 315 } 316 else{ 317 v0.push_back(make_pair((e[L[pos]].z+e[pos].z<<1)+1,0)); 318 v[k].push_back(make_pair((e[L[pos]].z+e[pos].z<<1)+1,pos)); 319 } 320 } 321 } 322 void unique(){ 323 sort(v0.begin(),v0.end()); 324 q=0; 325 for(int i=0;i<v0.size();i++){ 326 if ((!i)||(v0[i].fi!=v0[i-1].fi))Pos[++q]=v0[i].fi; 327 int pos=abs(v0[i].se); 328 if (v0[i].se>0)dS1[q]=Calc::add(dS1[q],z1[pos]),dS2[q]=Calc::add(dS2[q],z2[pos]); 329 else dS1[q]=Calc::dec(dS1[q],z1[pos]),dS2[q]=Calc::dec(dS2[q],z2[pos]); 330 } 331 } 332 void calc(){ 333 sort(v0.begin(),v0.end()); 334 S1=S2=0,ans.len=10; 335 for(int i=0;i<v0.size();i++){ 336 int pos=abs(v0[i].se); 337 if (v0[i].se>0)S1=Calc::add(S1,z1[pos]),S2=Calc::add(S2,z2[pos]); 338 else S1=Calc::dec(S1,z1[pos]),S2=Calc::dec(S2,z2[pos]); 339 if ((i==v0.size())||(v0[i].fi!=v0[i+1].fi)){ 340 if (!v0[i].fi)Check=S1; 341 ans=Calc::min(ans,Calc::dec(S2,Calc::mul(S1,S1))); 342 } 343 } 344 S1=S2=0; 345 memset(vis0,0,sizeof(vis0)); 346 for(int i=0;i<v0.size();i++){ 347 int pos=abs(v0[i].se); 348 vis0[pos]^=1; 349 if (v0[i].se>0)S1=Calc::add(S1,z1[pos]),S2=Calc::add(S2,z2[pos]); 350 else S1=Calc::dec(S1,z1[pos]),S2=Calc::dec(S2,z2[pos]); 351 if (((i==v0.size())||(v0[i].fi!=v0[i+1].fi))&&(!Calc::cmp(ans,Calc::dec(S2,Calc::mul(S1,S1)))))break; 352 } 353 } 354 void calc(int k){ 355 for(int i=0;i<v[k].size();i++){ 356 int q0=lower_bound(Pos+1,Pos+q+1,v[k][i].fi)-Pos,pos=abs(v[k][i].se); 357 if (v[k][i].se>0)dS1[q0]=Calc::add(dS1[q0],z1[pos]),dS2[q0]=Calc::add(dS2[q0],z2[pos]); 358 else dS1[q0]=Calc::dec(dS1[q0],z1[pos]),dS2[q0]=Calc::dec(dS2[q0],z2[pos]); 359 } 360 if (Calc::cmp(dS1[1],Check)<0){ 361 ans=-1; 362 return; 363 } 364 S1=S2=0,ans.len=10; 365 for(int i=1;i<=q;i++){ 366 S1=Calc::add(S1,dS1[i]),S2=Calc::add(S2,dS2[i]); 367 ans=Calc::min(ans,Calc::dec(S2,Calc::mul(S1,S1))); 368 } 369 for(int i=0;i<v[k].size();i++){ 370 int q0=lower_bound(Pos+1,Pos+q+1,v[k][i].fi)-Pos,pos=abs(v[k][i].se); 371 if (v[k][i].se<0)dS1[q0]=Calc::add(dS1[q0],z1[pos]),dS2[q0]=Calc::add(dS2[q0],z2[pos]); 372 else dS1[q0]=Calc::dec(dS1[q0],z1[pos]),dS2[q0]=Calc::dec(dS2[q0],z2[pos]); 373 } 374 } 375 int main(){ 376 n=IO::read(),m=IO::read(),T=IO::read(); 377 for(int i=1;i<=m;i++){ 378 e[i].x=IO::read(),e[i].y=IO::read(),e[i].z=IO::read(); 379 e[i].id=i; 380 } 381 sort(e+1,e+m+1); 382 LCT::init(); 383 for(int i=1;i<=m;i++){ 384 z1[i]=e[i].z; 385 z2[i]=Calc::mul(n-1,Calc::mul(z1[i],z1[i])); 386 } 387 get_LR(); 388 if (LCT::vis[0]!=n-1){ 389 if (T==1)IO::write(-1,'\n'); 390 else{ 391 for(int i=1;i<=m;i++)IO::write(-1,'\n'); 392 } 393 return 0; 394 } 395 get_v(),calc(); 396 if (T==1){ 397 IO::write(ans,'\n'); 398 return 0; 399 } 400 for(int i=1;i<=m;i++) 401 if (!vis0[i])Ans[e[i].id]=ans; 402 get_T12(); 403 for(int i=1;i<=m;i++) 404 if (vis0[i])upd_LR(i),upd_v(i); 405 unique(); 406 for(int i=1;i<=m;i++) 407 if (vis0[i]){ 408 calc(i); 409 Ans[e[i].id]=ans; 410 } 411 for(int i=1;i<=m;i++)IO::write(Ans[i],'\n'); 412 return 0; 413 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步