21牛客多校第六场

A

计算几何 咕

B

很猛的数学题 咕

C

共有\(\binom{n}{3}\)个三元环,\(\binom{n}{2}\)条边,要删到\(n-1\)条边

需要至少删\(\frac{1}{3}(\frac{n(n-1)}{2}-(n-1))=\frac{(n-1)(n-2)}{6}\)个没有重复边的三元环

考虑将\(\binom{n}{3}\)个三元环\((i,j,k)\)按照\((i+j+k)\%n\)分组,这样显然组内的三元环不会出现重复边

\(\frac{\binom{n}{3}}{n}=\frac{(n-1)(n-2)}{6}\),即这样分组一定会有一组内三元环数量\(>\frac{(n-1)(n-2)}{6}\)满足要求

可以打表找到对于每个\(n\)来说满足要求的三元组余数是多少,\(n^2\)枚举其中两点\(check\)

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp(a,b) make_pair(a,b)
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,x,t,res,seed[2005]={0,0,0,0,0,3,3,1,3,0,1,0,6,3,8,12,1,10,6,0,13,0,20,17,12,3,16,12,14,3,6,29,11,9,12,12,3,11,19,33,18,0,3,5,17,21,11,36,18,0,4,9,37,1,15,20,6,21,13,57,24,6,15,30,15,40,39,9,36,66,50,34,45,64,54,18,52,2,60,21,46,42,26,68,60,51,36,51,57,24,33,78,74,0,25,35,51,92,0,45,36,10,0,6,101,96,13,103,54,86,52,69,107,37,93,40,113,84,21,56,75,82,31,33,63,44,54,69,108,114,126,17,39,62,21,114,58,48,126,115,77,21,0,44,51,0,17,6,105,68,99,102,101,0,114,137,51,61,124,84,55,67,159,110,15,153,144,158,135,56,19,165,122,136,12,79,97,93,154,3,9,133,157,93,139,80,183,161,148,132,178,134,6,4,128,33,135,150,39,134,140,156,192,66,108,4,60,120,60,81,42,151,40,54,145,43,33,121,167,138,181,78,45,108,153,51,3,29,171,151,179,120,127,0,36,170,28,96,185,91,210,179,145,3,200,10,36,192,23,228,75,190,138,27,113,66,233,102,39,20,68,81,250,214,252,125,97,135,115,85,177,151,62,177,194,217,243,116,36,162,108,52,246,194,84,156,220,0,48,11,111,126,83,76,96,55,123,246,266,19,0,292,283,195,150,63,243,228,74,144,187,284,216,68,188,192,160,284,177,32,58,306,242,96,54,44,201,252,155,299,30,112,128,129,63,284,231,197,56,312,6,183,45,110,113,339,107,250,36,38,160,153,198,257,204,307,99,288,33,29,303,175,289,114,133,73,219,224,58,6,352,354,360,104,212,279,315,46,111,370,176,285,140,305,366,120,140,84,29,366,297,358,3,207,367,75,123,273,374,213,51,260,321,269,183,120,62,293,219,134,326,75,185,156,183,390,44,162,217,355,267,368,44,351,184,197,390,194,82,42,335,271,33,142,230,369,42,67,12,15,392,291,96,321,339,111,129,12,302,265,423,217,24,111,308,163,12,260,319,33,342,319,327,19,441,66,463,206,339,366,287,390,138,103,246,3,243,258,347,34,447,278,132,39,146,93,99,447,415,315,367,489,447,440,282,63,110,270,408,52,405,60,305,117,462,470,22,249,274,415,165,105,260,375,64,331,474,356,484,423,509,321,285,212,348,138,425,460,519,233,156,450,162,95,198,319,252,114,58,106,135,26,286,264,375,48,360,29,413,471,134,206,540,104,334,0,523,58,288,268,232,540,197,218,105,470,246,561,464,237,51,31,266,555,345,464,99,512,501,345,260,138,162,519,269,246,294,142,510,468,359,12,410,40,339,534,507,120,594,401,423,57,21,30,308,1,222,111,525,18,143,229,147,32,578,54,460,478,249,450,541,171,402,435,396,86,357,288,462,62,54,2,54,168,618,53,171,580,538,6,496,473,255,391,70,327,360,414,408,628,117,39,621,361,39,153,351,21,168,412,255,295,12,573,466,216,399,163,410,384,217,28,552,559,412,657,129,4,252,338,113,39,552,20,198,648,259,681,90,556,399,129,234,297,236,377,312,623,253,570,91,289,282,528,669,15,158,642,39,433,296,522,614,394,297,505,443,558,238,319,21,355,118,510,569,83,90,679,485,690,281,55,618,79,126,102,672,583,111,282,177,618,580,165,123,500,355,168,270,693,375,254,457,207,367,234,9,391,201,690,226,703,303,441,472,171,747,105,651,665,243,27,391,409,375,58,661,165,568,617,291,669,35,543,441,756,63,757,476,678,601,761,96,624,350,33,311,227,411,609,49,54,60,316,255,655,683,336,691,165,672,257,112,459,723,382,666,734,203,273,134,15,708,255,589,249,677,333,303,689,466,30,156,302,342,225,810,156,314,442,441,686,317,57,657,466,594,764,453,522,49,226,666,684,446,87,424,838,852,700,515,306,625,347,123,411,197,837,106,643,852,457,292,324,854,399,402,335,322,669,231,695,207,616,103,696,393,122,567,422,366,606,514,371,600,794,881,81,610,637,399,259,310,417,493,891,18,181,697,819,259,481,300,226,684,855,867,739,825,16,592,513,357,670,66,607,123,381,786,868,306,757,820,909,529,93,720,521,202,69,823,631,645,781,900,288,869,780,375,94,739,801,409,58,87,499,513,951,158,489,180,263,876,549,592,174,81,258,944,648,915,579,321,281,768,483,64,257,408,96,966,912,205,240,333,858,141,108,866,255,174,672,416,399,689,929,24,783,972,588,436,356,21,258,673,267,789,254,618,880,133,267,791,532,81,382,676,348,728,612,303,883,848,318,118,780,312,808,916,990,1006,898,864,799,941,357,770,934,186,697,374,921,822,460,1017,214,686,267,356,885,348,7,1024,438,594,816,471,721,8,378,176,526,99,87,959,405,655,276,507,401,985,444,30,320,702,465,183,669,886,317,708,157,955,147,372,125,813,168,271,111,377,936,351,583,656,291,316,789,774,911,530,75,674,768,99,18,752,261,713,946,486,980,157,384,128,708,462,980,866,930,326,292,312,456,790,960,758,722,84,939,790,90,178,616,540,1048,1037,537,863,988,555,1048,380,552,330,372,378,55,943,120,37,299,42,128,958,1080,141,270,117,13,111,699,1115,255,537,21,843,210,955,147,906,613,128,1020,470,1165,618,1024,243,501,418,314,339,1060,37,597,295,551,138,1090,1017,1080,92,616,561,3,151,570,238,838,774,412,337,1191,950,342,1143,83,534,855,271,741,855,18,1018,1173,815,582,114,235,784,888,1153,264,1089,114,469,690,240,271,0,97,1167,726,615,625,750,440,219,315,687,983,1074,980,1130,834,321,879,1101,1054,797,1071,32,1166,486,397,177,969,950,1157,1062,1030,566,1101,499,116,363,606,331,6,702,257,1047,1108,350,387,1166,1108,1173,47,695,54,337,845,915,708,565,264,138,825,939,13,1156,813,1031,72,249,346,258,585,892,787,483,1297,786,894,1224,684,1302,303,683,177,602,375,1173,1138,1286,888,767,123,1068,428,136,1020,1209,917,942,1205,695,1287,549,17,912,1280,435,1317,975,128,1203,1079,798,540,9,344,402,883,458,1155,1178,457,1050,1075,962,6,79,236,321,864,1199,1350,133,126,999,518,294,1170,1290,183,819,1088,322,402,531,299,39,187,332,774,580,413,54,140,844,1020,280,822,282,1120,832,252,1386,704,144,442,371,669,340,1348,564,1083,1099,708,455,778,237,213,1369,1329,352,817,150,1031,806,621,1122,437,1299,17,799,150,920,424,534,862,979,603,518,166,1311,732,724,864,1385,72,864,471,1170,606,1298,496,528,988,1390,144,790,917,585,831,840,741,587,251,1218,308,1032,165,725,389,1251,39,223,483,486,511,1077,351,459,1062,1152,648,984,834,233,702,539,762,54,1448,1189,1131,34,56,1362,853,635,1431,1473,241,1230,582,994,1434,828,1376,1317,703,883,1422,596,402,1110,220,222,354,1322,679,510,1459,4,390,586,476,1071,965,1381,1083,1243,12,984,850,390,102,771,75,807,1315,521,909,609,566,576,90,69,777,1471,1119,984,1243,742,201,1435,1422,57,671,13,402,433,91,276,878,1466,1023,1232,1535,1371,580,919,111,318,568,858,265,1069,861,613,1141,60,781,1132,1005,791,392,450,1266,1190,1116,1066,627,534,493,806,1425,1574,784,1485,448,1193,1038,856,180,798,179,823,792,1013,770,555,849,337,705,576,669,96,1212,382,1578,573,469,954,459,966,237,911,1368,540,777,713,393,549,1110,615,11,1448,465,1393,1111,27,1009,933,141,1419,251,1320,581,1182,1476,762,53,948,707,846,1563,159,437,561,670,917,1572,921,877,1239,1599,1212,501,1344,422,579,157,607,1611,192,78,960,81,234,1317,139,1050,567,715,1342,1071,69,7,609,823,1104,474,487,599,1125,110,1413,99,1158,683,444,1298,119,1629,321,1550,1179,1344,313,1389,1047,1556,297,1389,1591,1356,668,1206,63,633,760,249,11,534,1194,1345,55,957,1653,280,1059,1544,1311,918,1042,1075,1314,921,166,1020,73,1119,1431,1497,1073,369,789,390,804,199,583,1164,1237,1282,657,174,190,1521,1633,406,1620,527,534,450,1359,452,1140,591,890,1584,996,1526,1152,143,1431,648,657,1278,1467,474,1340,1299,914,1715,231,1579,704,987,816,440,1362,610,10,687,850,1043,1383,860,177,186,1385,345,1368,1653,330,765,1782,845,36,1178,1351,540,1490,150,327,563,1232,351,88,857,1143,1152,1163,855,847,177,1638,750,152,1356,410,502,660,148,883,1407,1535,1376,1572,1360,1457,993,605,523,702,1406,1625,33,1789,1725,144,84,1780,1536,396,621,783,331,932,726,653,1829,1641,915,25,1539,1211,551,1545,1639,1086,570,125,783,1272,910,475,1827,397,588,1821,1383,229,1701,997,271,1293,335,1755,75,706,1767,582,871,164,1548,617,1247,1686,1753,851,1692,1714,419,327,498,1831,942,477,967,213,372,435,1479,1402,683,1518,1715,1665,1416,1621,216,1734,989,416,1095,1760,1433,861,594,633,1167,138,1151,906,38,1586,1230,1762,1656,411,1580,10,534,302,198,1059,56,885,1239,920,311,1260,907,969,507,1440,1482,660,247,49,1404,1682,1692,1341,1080,1169,471,138,1920,906,309,428,411,1854,708,741,1313,244,564,1430,1023,1398,152,1620,108,897,1901,315,1121,1000,1176,109,1825,1959,85,1771,1623,463,764,540,25,72,1173,661,1545,1443,779,541,252,541,1456,792,16,1743};
map<pii,int> m;
vector<pii> ans;
int main()
{
	n=read(),t=seed[n];
	int i,j,k;
	rep(x,0,n-1) rep(y,x+1,n-1)
	{
		i=x,j=y,k=((t-x-y)%n+n)%n;
		if(k==i||k==j) continue;
		if(i>k&&i>j) swap(i,k);
		if(j>k&&j>i) swap(j,k);
		if(i>j) swap(i,j);
		if(!m[{i,j}]) m[{i,j}]=1,ans.pb({i,j});
	}
	printf("%d\n",ans.size());
	for(auto x:ans) printf("%d %d %d\n",x.fi+1,x.se+1,((t-x.fi-x.se)%n+n)%n+1);
}

D

\(E_x\)为当前数为\(x\)时的期望步数,有朴素的方程\(E_x=(E_x+1)(1-\sum\limits_{x\otimes y>x}P_y)+\sum\limits_{x\otimes y=z,z>x}E_z+1\)

移项得:\([\sum\limits_{x\otimes y>x}P_y](E_x+1)=1+\sum\limits_{x\otimes y=z,z>x}E_z+1\)

\(\sum\limits_{x\otimes y>x}P_y\)即为所有满足\(y\)最高位\(1\)\(x\)该位为\(0\)\(y\),可以预处理

同时发现后半部分转移从右往左单向转移且形式与\(fwt\)一致,考虑分治\(fwt\)

对于区间\([l,r]\)来说,异或的过程实际上是\([mid+1,r]\)区间的\(E\)\([mid+1-l,r-l]\)内的\(P\)异或转移到\([l,mid]\)内的\(E\)

注意端点处按照式子求出\(E_x+1=\frac{1+\sum\limits_{x\otimes y=z,z>x}(E_z+1)}{\sum\limits_{x\otimes y>x}P_y}\)

最终\(E_0+1\)即为答案

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 1000000007
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int qp(int x,int t,int res=1)
{
	for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);
	return res;
}
#define inv(x) qp(x,MOD-2)
const int inv2=inv(2);
int n,p[MAXN],ans,f[MAXN],g[MAXN],A[MAXN],B[MAXN],h[20];
void trans(int &a,int &b){int x=a,y=b;a=pls(x,y),b=mns(x,y);}
void itrans(int &a,int &b){int x=a,y=b;a=mul(pls(x,y),inv2),b=mul(mns(x,y),inv2);}
void fwt(int *a,int n,int t)
{
	for(int i=1;i<n;i<<=1) for(int j=0;j<n;j+=i<<1) rep(k,0,i-1)
		if(!t) trans(a[j+k],a[j+k+i]);
		else itrans(a[j+k],a[j+k+i]);
}
void solve(int *a,int *b,int n)
{
	rep(i,0,n-1) A[i]=a[i],B[i]=b[i];fwt(A,n,0);fwt(B,n,0);
	rep(i,0,n-1) A[i]=mul(A[i],B[i]);fwt(A,n,1);
}
void Div(int l,int r)
{
	if(l==r)
	{
		int sum=0;dwn(i,15,0) if(!((l>>i)&1)) sum=pls(h[i],sum);
		sum=inv(sum);f[l]=mul(sum,f[l]+1);return ;
	}
	int mid=l+r>>1;Div(mid+1,r);
	solve(f+mid+1,p+mid+1-l,r-mid);
	rep(i,l,mid) f[i]=pls(f[i],A[i-l]);Div(l,mid);
}
int main()
{
	int sum;rep(T,1,read())
	{
		n=read();sum=0;Fill(h,0);
		rep(i,0,n-1) p[i]=read(),sum=pls(p[i],sum),f[i]=0;
		sum=inv(sum);rep(i,0,n-1) p[i]=mul(p[i],sum);
		for(int t=0,k=1;k<n;t++,k<<=1)
			rep(i,k,(k<<1)-1) h[t]=pls(h[t],p[i]);
		Div(0,n-1);printf("%d\n",f[0]);
	}
}

E

替罪羊树 咕

F

答案显然是所有物品均摊或所有物品时间的最大值

直接暴力的安排所有物品

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,g[MAXN],id;
ll sum,ans,now;
int main()
{
	n=read(),m=read();
	rep(i,1,n) g[i]=read(),sum+=g[i],ans=max(ans,(ll)g[i]);
	ans=max(ans,(sum+m-1)/m);now=0;id=1;
	rep(i,1,n)
	{
		if(now+g[i]<=ans)
			printf("1 %d %lld %lld\n",id,now,now+g[i]);
		else
		{
			printf("2 %d %lld %lld %d %lld %lld\n",id+1,0,now+g[i]-ans,id,now,ans);
			now-=ans,id++;
		}
		now+=g[i];if(now==ans) id++,now=0;
	}
}

G

\(Min\_25\)筛 咕

H

将所有禁止的区域都放到\((0,0),(d-1,d-1)\)这个矩形里,需要拆一下矩形

则问题转化为了在\((0,0),(d-1,d-1)\)这个矩形中找到一个没有被覆盖过的点

用扫描线+线段树维护,线段树维护一下区间最小值,若出现\(0\)则说明有没被覆盖过的点

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,mn[MAXN<<2],tag[MAXN<<2],lim,rx,ry;
struct node{int l,r,w;};
vector<node> v[MAXN];
inline void pshd(int k)
{
	tag[k<<1]+=tag[k],tag[k<<1|1]+=tag[k];
	mn[k<<1]+=tag[k],mn[k<<1|1]+=tag[k];
	tag[k]=0;
}
void mdf(int k,int l,int r,int a,int b,int w)
{
	if(a<=l&&r<=b) {tag[k]+=w,mn[k]+=w;return ;}
	int mid=l+r>>1;if(tag[k]) pshd(k);
	if(a<=mid) mdf(k<<1,l,mid,a,b,w);
	if(b>mid) mdf(k<<1|1,mid+1,r,a,b,w);
	mn[k]=min(mn[k<<1],mn[k<<1|1]);
}
int find(int k,int l,int r)
{
	if(l==r) return l;int mid=l+r>>1;pshd(k);
	if(!mn[k<<1]) return find(k<<1,l,mid);
	else return find(k<<1|1,mid+1,r);
}
int main()
{
	n=read(),lim=read();int x1,y1,x2,y2;
	rep(i,1,n)
	{
		x1=read(),y1=read(),x2=read(),y2=read();
		if(abs(x2-x1)>=lim) x1=0,x2=lim;
		else x1=(x1%lim+lim)%lim,x2=(x2%lim+lim)%lim;
		if(abs(y2-y1)>=lim) y1=0,y2=lim-1;
		else y1=(y1%lim+lim)%lim,y2=(y2%lim+lim-1)%lim;
		if(y1<=y2)
		{
			v[x1].pb({y1,y2,1});
			v[x2].pb({y1,y2,-1});
			if(x1>x2) v[0].pb({y1,y2,1});
		}
		else 
		{
			v[x1].pb({0,y2,1});v[x1].pb({y1,lim-1,1});
			v[x2].pb({0,y2,-1});v[x2].pb({y1,lim-1,-1});
			if(x1>x2) {v[0].pb({0,y2,1});v[0].pb({y1,lim-1,1});}
		}
	}
	rx=ry=-1;rep(i,0,lim-1)
	{
		for(auto t:v[i])
			mdf(1,0,lim-1,t.l,t.r,t.w);
		if(!mn[1]) 
		{
			rx=i,ry=find(1,0,lim-1);break;
		}
	}
	if(rx<0||ry<0) puts("NO");
	else printf("YES\n%d %d\n",rx,ry);
}

I

把给出的区间通过合并变为一些不相邻的区间

对于这些区间,选出每个区间的左端点和上一个区间的右端点作为新的区间,这样选出的\(n\)个区间符合条件

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,tot;
struct seg{int l,r;}g[1010];
bool operator < (seg a,seg b) {return a.l<b.l;}
int main()
{
	rep(T,1,read())
	{
		n=read(),m=read();rep(i,1,m) g[i].l=read(),g[i].r=read();
		tot=0;sort(g+1,g+m+1);
		rep(i,1,m)
			if(i==1||g[i].l!=g[tot].r+1) g[++tot]=g[i];
			else g[tot].r=g[i].r;
		if(tot>1&&g[tot].r+1==g[1].l) g[1].l=g[tot].l,tot--;
		if(tot==1) printf("1\n%d %d\n",g[1].l,g[1].r);
		else
		{
			printf("%d\n",tot);
			rep(i,1,tot) printf("%d %d\n",g[i].l,g[(i+tot-2)%tot+1].r);
		}
	}
}

J

对于\(n\)为偶数的情况,显然不需要删点

否则我们希望删掉奇数个点使得剩余一些偶数连通块

删除的奇数个点一定为独立的,否则对一个点数为奇数的连通块,可以删掉其中一个点使得答案更大

期望的情况是找到一个最小的点并删除它,若这个点并非割点则显然可以

若不是割点,不妨设方案为删除奇数个割点使得最终剩余一些偶数连通块

对于这些割点,若选择以这些割点构成的虚树上的叶子节点,则可以使剩余偶数个割点在一个连通块内,使答案增大

因此最终的方案一定是选择一个非割点或选一个相邻点双均为偶数的割点删除

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 1001001
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,cnt,fst[MAXN],to[MAXN<<1],nxt[MAXN<<1],w[MAXN];
int dfn[MAXN],low[MAXN],sz[MAXN],stp,ban[MAXN],ans;
ll sum;
void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
void tarjan(int x,int fa)
{
    dfn[x]=low[x]=++stp,sz[x]=1;
	ren 
        if(!dfn[to[i]])
        {
            tarjan(to[i],x);sz[x]+=sz[to[i]];
            low[x]=min(low[x],low[to[i]]);
            if((low[to[i]]>=dfn[x])&&(sz[to[i]]&1)) ban[x]=1;
        }
        else if(dfn[to[i]]<dfn[x]&&to[i]!=fa) low[x]=min(low[x],dfn[to[i]]);
}
int main()
{
	int a,b;rep(T,1,read())
	{
		n=read(),m=read();rep(i,1,n) dfn[i]=fst[i]=ban[i]=0;
		stp=sum=cnt=0;ans=inf;
		rep(i,1,n) w[i]=read(),sum+=w[i];
		rep(i,1,m) a=read(),b=read(),add(a,b),add(b,a);
		if(n&1)
		{
			tarjan(1,0);
			rep(i,1,n) if(!ban[i]) ans=min(ans,w[i]);
			printf("%lld\n",sum-ans*2);
		}
		else printf("%lld\n",sum);
	}
}

K

猫树+点分治 咕

posted @ 2021-08-02 21:17  jack_yyc  阅读(70)  评论(0编辑  收藏  举报