Codeforces 2025年2月

\(CF915F\)
https://www.luogu.com.cn/problem/CF915F
题解:先拆解贡献,\(\sum\sum f(i,j)=\sum\sum mx(i,j)-\sum\sum mi(i,j)\)
下求\(\sum\sum mx(i,j)\),先将点权转边权,令边权\(w(i,j)=max(a_i,a_j)\),从小到大枚举每一条边,发现若当前边将连通块\(a,b\)相连,则\(\forall i\in a,j\in b,mx(i,j)=w\),模拟上述过程即可。
对于\(\sum\sum mi(i,j)\)的求解同上。

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int N=1e6+10;

int n,ans;
int a[N],p[N],sz[N];
struct Edge{
	int a,b,c;
}e[N];

bool cmp1(Edge t1,Edge t2){
	return t1.c<t2.c;
}

bool cmp2(Edge t1,Edge t2){
	return t1.c>t2.c;
}

int find(int x){
	if(x==p[x]) return x;
	return p[x]=find(p[x]);
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i];
	for(int i=1; i<=n-1; i++){
		int a,b;
		cin >> a >> b;
		e[i]={a,b};
	}
	for(int i=1; i<=n-1; i++) e[i].c=max(a[e[i].a],a[e[i].b]);
	sort(e+1,e+n,cmp1);
	for(int i=1; i<=n; i++) p[i]=i,sz[i]=1;
	for(int i=1; i<=n-1; i++){
		int a=e[i].a,b=e[i].b,c=e[i].c;
		a=find(a),b=find(b);
		ans+=sz[a]*sz[b]*c;
		p[a]=b,sz[b]+=sz[a];
	}
	for(int i=1; i<=n-1; i++) e[i].c=min(a[e[i].a],a[e[i].b]);
	sort(e+1,e+n,cmp2);
	for(int i=1; i<=n; i++) p[i]=i,sz[i]=1;
	for(int i=1; i<=n-1; i++){
		int a=e[i].a,b=e[i].b,c=e[i].c;
		a=find(a),b=find(b);
		ans-=sz[a]*sz[b]*c;
		p[a]=b,sz[b]+=sz[a];
	}
	cout << ans << endl;
	return 0;
}

\(CF915G\)
https://www.luogu.com.cn/problem/CF915G
题解:经过简单容斥,可知\(f(m)=\sum u(d)*{\lfloor \frac{m}{d} \rfloor}^n\),具体含义是以公因数是否含有某个质因子为性质去容斥,容斥系数为\(u(d)\),而由\(n\)个数组成的,每个数在\(1\sim m\),且公因数为\(d\)的倍数的数组个数,为\({\lfloor \frac{m}{d} \rfloor}^n\)
观察式子,提前预处理\(i^n\),可直接枚举\(m\),对\(d\)进行整除分块,复杂度为\(O(n\sqrt n)\)
考虑固定\(d\),发现\({\lfloor \frac{m}{d} \rfloor}^n\),也是随\(m\)一块块变化的,于是直接利用差分数组对\(f\)进行区间加即可。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=2e6+10,P=1e9+7;

int n,m,ans;
int u[N],g[N],f[N];
int prime[N],cnt;
bool st[N];

int qpow(int a,int b){
	int res=1;
	while(b){
		if(b&1) res=(LL)res*a%P;
		a=(LL)a*a%P;
		b>>=1;
	}
	return res;
}

void sieve(int n){
	u[1]=1;
	for(int i=2; i<=n; i++){
		if(!st[i]) prime[++cnt]=i,u[i]=-1;
		for(int j=1; j<=cnt&&prime[j]<=n/i; j++){
			st[i*prime[j]]=1;
			if(i%prime[j]==0) break;
			u[i*prime[j]]=-u[i];
		}
	}
}

int main(){
	sieve(N-1);
	cin >> n >> m;
	for(int i=1; i<=m; i++) g[i]=qpow(i,n);
	for(int i=1; i<=m; i++)
		for(int j=i; j<=m; j+=i){
			f[j]=(f[j]+u[i]*g[j/i])%P;
			if(j+i<=m) f[j+i]=(f[j+i]-u[i]*g[j/i])%P;
		}
	for(int i=1; i<=m; i++){
		f[i]=(f[i]+f[i-1])%P;
		f[i]=(f[i]%P+P)%P;
		ans=(ans+(f[i]^i))%P;
	}
	cout << ans << endl;
	return 0;
}

\(CF920D\)
https://www.luogu.com.cn/problem/CF920D
题解:\(v\)很大,\(k\)较小,往与\(k\)同余方向构造。
考虑选出一个集合,将集合内水合并,设集合水量为\(s\),要求\(s\equiv v(mod\ k)\)。若\(s>v\),则直接将集合中水盛出若干。若\(s<v\),则先将其余水合并,再盛入目标集合即可。对于求解所需集合,用背包即可。

#include <bits/stdc++.h>

using namespace std;

const int N=5010;

int n,k,v;
int a[N];
bool st[N],f[N][N];

int main(){
	cin >> n >> k >> v;
	for(int i=1; i<=n; i++) cin >> a[i];
	int sum=0;
	for(int i=1; i<=n; i++) sum+=a[i];
	if(sum<v){
		cout << "NO" << endl;
		return 0;
	}
	f[0][0]=1;
	for(int i=1; i<=n; i++)
		for(int j=0; j<k; j++)
			f[i][j]=f[i-1][j]|f[i-1][(j-(a[i]%k)+k)%k];
	if(!f[n][v%k]){
		cout << "NO" << endl;
		return 0;
	}
	cout << "YES" << endl;
	int x=n,y=v%k;
	while(1){
		if(!x) break;
		if(f[x-1][(y-(a[x]%k)+k)%k]) 
			st[x]=1,y=(y-(a[x]%k)+k)%k;
		x--;
	}
	vector<int> q1,q2;
	int sum1=0,sum2=0;
	for(int i=1; i<=n; i++)
		if(st[i]) q1.push_back(i);
		else q2.push_back(i);
	for(int i=0; i<q1.size(); i++) sum1+=a[q1[i]];
	for(int i=1; i<q1.size(); i++)
		if(a[q1[i]]) cout << (a[q1[i]]+k-1)/k << " " << q1[i] << " " << q1[0] << endl;
	for(int i=0; i<q2.size(); i++) sum2+=a[q2[i]];
	for(int i=1; i<q2.size(); i++) 	
		if(a[q2[i]]) cout << (a[q2[i]]+k-1)/k << " " << q2[i] << " " << q2[0] << endl;
	if(q1.size()==n) q2.push_back(n);
	else if(q2.size()==n) q1.push_back(n);
	if(sum1>v) cout << (sum1-v)/k << " " << q1[0] << " " << q2[0] << endl;
	else if(sum1<v) cout << (v-sum1)/k << " " << q2[0] << " " << q1[0] << endl;	
	return 0;
}

\(CF954I\)
https://www.luogu.com.cn/problem/CF954I
题解:注意字符种类小,直接枚举集合划分,总划分方案为\(B_6=203\)
对于每个方案,直接字符串哈希更新答案即可。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=2e5+10;
const int Base=131,P=998244353;

int n,m,cnt;
int s1[N],s2[N],Pow[N],ans[N];
vector<char> q[N];
char s[N],t[N],t1[N],t2[N];

void check(){
	memcpy(t1,s,sizeof s);
	memcpy(t2,t,sizeof t);
	for(int i=1; i<=cnt; i++){
		for(int j=1; j<=n; j++)
			for(int k=0; k<q[i].size(); k++)
				if(s[j]==q[i][k]) s[j]=q[i][0];
		for(int j=1; j<=m; j++)
			for(int k=0; k<q[i].size(); k++)
				if(t[j]==q[i][k]) t[j]=q[i][0];
	}
	for(int i=1; i<=n; i++) s1[i]=((LL)s1[i-1]*Base+s[i]-'a'+1)%P;
	for(int i=1; i<=m; i++) s2[i]=((LL)s2[i-1]*Base+t[i]-'a'+1)%P;
	for(int i=m; i<=n; i++) {
		int l=i-m+1,r=i,v=(LL)(s1[r]-(LL)s1[l-1]*Pow[r-l+1])%P;
		v=(v%P+P)%P;
		if(v==s2[m]) ans[i]=min(ans[i],6-cnt);
	}
	memcpy(s,t1,sizeof t1);
	memcpy(t,t2,sizeof t2);
	return;
}

void dfs(char ch){
	if(ch=='g'){
		check();
		return;
	}
	for(int i=1; i<=cnt; i++){
		q[i].push_back(ch);
		dfs(ch+1);
		q[i].pop_back();
	}
	q[++cnt].push_back(ch);
	dfs(ch+1);
	q[cnt--].pop_back();
}

int main(){
	Pow[0]=1;
	for(int i=1; i<N; i++) Pow[i]=(LL)Pow[i-1]*Base%P;
	cin >> s+1 >> t+1;
	n=strlen(s+1),m=strlen(t+1);
	memset(ans,0x3f,sizeof ans);
	dfs('a');
	for(int i=m; i<=n; i++) cout << ans[i] << " ";
	cout << endl;
	return 0;
}

\(CF954H\)
https://www.luogu.com.cn/problem/CF954H
题解:令\(p(i,j)=\prod_{k=i}^{i+j-1}a_k\)\(ans_i\)为长度为\(i\)路径数目。
考虑对路径在\(lca\)处统计答案。
若路径是一条直链,枚举\(lca\)深度,\(ans_d\leftarrow \sum_{i=1}^{n-1}p(i,d)*p(1,i-1)\),复杂度\(O(n^2)\)
若路径拐弯,先枚举\(lca\)深度,再枚举左右儿子所处子树,以及左右儿子深度。\(ans_d\leftarrow \sum_{i=1}^{n-1}C_{a_i}^{2}*p(1,i-1)\sum_{j=1}^{d-1}p(i+1,j-1)*p(i+1,d-j-1)\),复杂度\(O(n^3)\)
\(g_i=\prod_{k=1}^{i}a_i\),则有\(p(i,j)=\frac{g_{i+j-1}}{g_{i-1}}\)
于是\(ans_d\leftarrow \sum_{i=1}^{n-1}C_{a_i}^{2}\frac{g_{i-1}}{{g_i}^2}\sum_{j=1}^{d-1}g_{i+j-1}*g_{i+d-j-1}\)
\(f(d,i)=\sum_{j=1}^{d-1}g_{i+j-1}*g_{i+d-j-1}\),这是一个卷积式子,有\(f(d,i)=f(d-2,i+1)+2*g_i*g_{i+d-2}\),初值\(f(2,i)={g_i}^2\),复杂度\(O(n^2)\)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=2e4+10,P=1e9+7;

int n,inv2;
int a[N],ans[N];
int g[N],inv_g[N],f[N/2][N/4];

int qpow(int a,int b){
	int res=1;
	while(b){
		if(b&1) res=(LL)res*a%P;
		a=(LL)a*a%P;
		b>>=1;
	}
	return res;
}

int main(){
	inv2=qpow(2,P-2);
	cin >> n;
	for(int i=1; i<=n-1; i++) cin >> a[i];
	g[0]=1;
	for(int i=1; i<=n-1; i++) g[i]=(LL)g[i-1]*a[i]%P;
	for(int i=1; i<=n-1; i++) inv_g[i]=qpow(g[i],P-2);
	for(int i=1; i<=n-1; i++)
		for(int j=1; j<=2*n-2; j++)
			ans[j]=(ans[j]+(LL)g[i+j-1])%P;
	for(int i=1; i<=n-1; i++) f[2][i]=(LL)g[i]*g[i]%P;
	for(int i=3; i<=2*n-2; i++)
		for(int j=1; j<=n-1; j++)
			f[i][j]=(f[i-2][j+1]+(LL)2*g[j]*g[i+j-2])%P;
	for(int i=1; i<=n-1; i++)
		for(int j=1; j<=2*n-2; j++)
			ans[j]=(ans[j]+(LL)a[i]*(a[i]-1)%P*inv2%P*
			g[i-1]%P*inv_g[i]%P*inv_g[i]%P*f[j][i])%P;
	for(int i=1; i<=2*n-2; i++) cout << (ans[i]%P+P)%P << " ";
	cout << endl;
	return 0;
}

\(CF961F\)
https://www.luogu.com.cn/problem/CF961F
题解:若从大到小枚举\(k\),即从中间向两边扩展字符,注意到有\(ans_k\leq ans_{k+1}+2\),于是每次直接令答案加二,然后逐步减二,直到前后缀匹配。答案一共只会增加\(n\),用字符串哈希判断,复杂度\(O(n)\)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=1e6+10;
const int Base=131,P=998244353;


int n;
int s[N],Pow[N],ans[N];
char ch[N];

int calc(int l,int r){
	int v=(s[r]-(LL)s[l-1]*Pow[r-l+1])%P;
	v=(v%P+P)%P;
	return v;
}

int main(){
	Pow[0]=1;
	for(int i=1; i<N; i++) Pow[i]=(LL)Pow[i-1]*Base%P;
	cin >> n;
	for(int i=1; i<=n; i++) cin >> ch[i];
	for(int i=1; i<=n; i++) s[i]=((LL)s[i-1]*Base+ch[i]-'a'+1)%P;
	if(n%2) ans[(n+1)/2]=-1;
	else ans[(n+1)/2]=ch[n/2]==ch[n/2+1]?1:-1;
	for(int k=(n+1)/2-1; k; k--){
		int l=k,r=n-k+1;
		ans[k]=ans[k+1]+(ans[k+1]==-1?4:2);
		if(ans[k]==r-l+1) ans[k]-=2;
		while(1){
			if(ans[k]==-1) break;
			if(calc(l,l+ans[k]-1)==calc(r-ans[k]+1,r)) break;
			ans[k]-=2;
		}
	}
	for(int i=1; i<=(n+1)/2; i++) cout << ans[i] << " ";
	cout << endl;
	return 0;
} 

\(CF961G\)
https://www.luogu.com.cn/problem/CF961G
题解:对每个点单独算贡献,即先枚举每个点,再枚举这个点所处集合大小。
\(ans=\sum_{i=1}^{n} w_i\sum_{j=1}^{n}j*C_{n-1}^{j-1}*S_{n-j}^{j-1}\)
下面就是漫长的推式子环节。
先给出几条相关性质:
\(1:S_{n}^{m}=\frac{1}{m!}\sum_{i=0}^{m}(-1)^iC_{m}^{i}(m-i)^n\)
解释:考虑先给集合加编号,然后针对性质:集合内有没有元素,进行容斥,最后对集合去序。
\(2:kC_{n}^{k}=nC_{n-1}^{k-1}\)
解释:直接对组合数拆解可得。
\(3:\sum_{i=0}^{n}C_{n}^{i}(k-1)^{n-i}=k^n\)
解释:平凡的二项式定理。
具体式子推导详见下图:

笔误了,图中答案最后分母应为\(i!(k-i-1)!\)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=2e5+10,P=1e9+7;

int qpow(int a,int b){
	if(b<0) return qpow(qpow(a,-b),P-2);
	int res=1;
	while(b){
		if(b&1) res=(LL)res*a%P;
		a=(LL)a*a%P;
		b>>=1;
	}
	return res;
}

int main(){
	int fac[N]={};
	fac[0]=1;
	for(int i=1; i<N; i++) fac[i]=(LL)fac[i-1]*i%P;
	int n,k,res=0,ans=0;
	cin >> n >> k;
	for(int i=1; i<=n; i++){
		int x;
		cin >> x;
		ans=(ans+x)%P;
	}
	for(int i=0; i<=k-1; i++)
		res=(res+(LL)qpow(-1,i)*qpow(k-i,n-2)%P*(k-i+n-1)%P
		*qpow(fac[i],P-2)%P*qpow(fac[k-i-1],P-2))%P;
	ans=(LL)ans*res%P;
	ans=(ans%P+P)%P;
	cout << ans << endl;
	return 0;
} 

\(CF990F\)
https://www.luogu.com.cn/problem/CF990F
题解:若\(\sum s_i\)不为\(0\),则一定无解。否则,将图生成为一棵树,忽略非树边,自下而上递推树边即可。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int N=2e5+10;

int n,m;
int a[N],ans[N];
int h[N],e[2*N],ne[2*N],idx;
bool st[N];

void add(int a,int b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

void dfs(int u,int fa){
	st[u]=1;
	for(int i=h[u]; i!=-1; i=ne[i]){
		int j=e[i];
		if(j==fa||st[j]) continue;
		dfs(j,u);
		a[u]+=a[j];
		if((a[j]>0)==(i%2==0)) ans[i/2]=abs(a[j]);
		else ans[i/2]=-abs(a[j]);
	}
}

int main(){
	memset(h,-1,sizeof h);
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i];
	cin >> m;
	for(int i=1; i<=m; i++){
		int a,b;
		cin >> a >> b;
		add(a,b),add(b,a);
	}
	LL sum=0;
	for(int i=1; i<=n; i++) sum+=a[i];
	if(sum){
		cout << "Impossible" << endl;
		return 0;
	}
	dfs(1,-1);
	cout << "Possible" << endl;
	for(int i=0; i<idx; i+=2) cout << ans[i/2] << endl;
	return 0;
}

\(CF1027F\)
https://www.luogu.com.cn/problem/CF1027F
题解:将考试和时间看成两个点集,集合间连边,所求即为二分图的一组匹配,使得左侧点集被全选,最小化右侧最大点。
模拟匈牙利算法,先尝试能不能选\(a\),若\(a\)没被选过,则选\(a\),若选过,则尝试能否让之前匹配\(a\)的人换一个选择,不断递归,再尝试能不能选\(b\),流程同上。
设在选\(a\)过程中,右侧新加入点为\(ta\),选\(b\)过程中,右侧新加入点为\(tb\)
分类讨论,若\(ta\)\(tb\)都能选,贪心的选更小的那个。
\(ta\)\(tb\)仅有一个能被选,选择那一个,并且其永久删除。
\(ta\)\(tb\)都不能被选,则直接输出\(-1\)
将操作刻画在并查集上,对于情况\(1\),假设选取\(ta\),将\(ta\)接到\(tb\)下,代表以后可用\(tb\)替换\(ta\)
对于情况\(2\),删除点\(ta\),即将\(ta\)接到\(0\)下即可。
对于情况\(3\),判断是否\(ta,tb\)均为\(0\)即可。
以上做法正确性是基于在以上操作下,的确只有并查集的根是可选的,非根节点一定以及在右侧点集里,归纳法易证。

#include <bits/stdc++.h>

using namespace std;

const int N=1e6+10;

int n;
int a[N],b[N],p[N];
vector<int> alls;
map<int,int> M;

int find(int x){
	if(x==p[x]) return x;
	return p[x]=find(p[x]);
}

int main(){
	cin >> n;
	for(int i=1; i<=n; i++){
		cin >> a[i] >> b[i];
		alls.push_back(a[i]);
		alls.push_back(b[i]);
	}
	sort(alls.begin(),alls.end());
	alls.erase(unique(alls.begin(),alls.end()),alls.end());
	for(int i=0; i<alls.size(); i++) M[alls[i]]=i+1;
	for(int i=1; i<=n; i++) a[i]=M[a[i]],b[i]=M[b[i]];
	for(int i=1; i<=alls.size(); i++) p[i]=i;
	for(int i=1; i<=n; i++){
		int ta=find(a[i]),tb=find(b[i]);
		if(ta>tb) swap(ta,tb);
		if(ta&&tb){
			if(ta==tb) p[ta]=0;
			else p[ta]=tb;
		}
		else if(ta) p[ta]=0;
		else if(tb) p[tb]=0;
		else{
			cout << -1 << endl;
			return 0;
		}
	}
	int ans=0;
	for(int i=1; i<=alls.size(); i++)
		if(p[i]!=i) ans=max(ans,alls[i-1]);
	cout << ans << endl;
	return 0;
}

\(CF1036E\)
https://www.luogu.com.cn/problem/CF1036E
题解:直接枚举线段,计算其上整点数,再减去与先前线段的交点即可。
主要讲解如何进行线段求交,考虑将线段看成设线,并改写为参数方程的形式,即
\(x=x_0+k*d1,y=y_0+k*d2\)
联立两参数方程求得交点,判断交点是否在两条线段上即可。

#include <bits/stdc++.h>
#define int long long

using namespace std;

typedef pair<int,int> PII;
const int N=1010,INF=1e9;

int n,ans;
struct Segment{
	int x1,y1,x2,y2;
}seg[N];

void exgcd(int a,int b,int &x,int &y){
	if(!b){
		x=1,y=0;
		return;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}

PII Intersection(Segment a,Segment b){
	int x1=a.x1,y1=a.y1;
	int d1=(a.x2-a.x1)/__gcd(abs(a.x1-a.x2),abs(a.y1-a.y2));
	int d2=(a.y2-a.y1)/__gcd(abs(a.x1-a.x2),abs(a.y1-a.y2));
	int x2=b.x1,y2=b.y1;
	int d3=(b.x2-b.x1)/__gcd(abs(b.x1-b.x2),abs(b.y1-b.y2));
	int d4=(b.y2-b.y1)/__gcd(abs(b.x1-b.x2),abs(b.y1-b.y2));
	//cout << x1 << " " << x2 << " " << d1 << " " << d3 << endl;
	//return{INF,INF};
	int x=x2-x1,y=y2-y1,td1=d1,td2=d2,td3=d3,td4=d4;
	//cout << x << " " << y << " " << d1 << " " << d2 << " " << d3 << " " << d4 << endl;
	x*=td4,d1*=td4,d3*=td4;
	y*=td3,d2*=td3,d4*=td3;
	int A=x-y,B=d1-d2;
	//cout << A << " " << B << endl;
	if(!B||A%B) return{INF,INF};
	int k=A/B;
	return {x1+k*td1,y1+k*td2};
}

bool check(PII p,Segment t){
	if(p.first<min(t.x1,t.x2)||p.first>max(t.x1,t.x2)) return 0;
	if(p.second<min(t.y1,t.y2)||p.second>max(t.y1,t.y2)) return 0;
	return 1;
}

signed main(){
	cin >> n;
	for(int i=1; i<=n; i++){
		int x1,y1,x2,y2;
		cin >> x1 >> y1 >> x2 >> y2;
		seg[i]={x1,y1,x2,y2};
		ans+=__gcd(abs(x1-x2),abs(y1-y2))+1;
		vector<PII> q;
		for(int j=1; j<=i-1; j++){
			PII p=Intersection(seg[i],seg[j]);
			//cout << i << " " << j << " " << p.first << " " << p.second << " OK" << endl;
			if(check(p,seg[i])&&check(p,seg[j])) q.push_back(p);
		}
		sort(q.begin(),q.end());
		q.erase(unique(q.begin(),q.end()),q.end());
		ans-=q.size();
	}
	cout << ans << endl;
	return 0;
}

\(CF1036F\)
https://www.luogu.com.cn/problem/CF1036F
题解:考虑容斥,减去不满足条件的数,发现所有不满足条件的数,都可化为\(a^b,b\geq 2\)的形式。
对于\(b=2\)时,直接用\(\sqrt n\)计算即可,对于\(b\geq 3\)的时候,考虑取出所有\(a^b,b\geq 3\),排序去重,注意在此过程要避免\(b=2\)的情况。
对于查询,直接在处理好后序列内二分即可,再加上\(\sqrt n\)

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int N=1e6+10,INF=1e18;

bool check(int x){
	int t=(int)sqrt(x);
	return t*t<x;
}

signed main(){
	vector<int> q;
	for(int i=2; i<=1000000; i++){
		int t=i*i;
		while(t<=INF/i){
			t*=i;
			if(check(t)) q.push_back(t);
		}
	}
	sort(q.begin(),q.end());
	q.erase(unique(q.begin(),q.end()),q.end());
	int T;
	cin >> T;
	while(T--){
		int n;
		cin >> n;
		int l=0,r=q.size();
		while(l<r){
			int mid=(l+r)/2;
			if(q[mid]>n) r=mid;
			else l=mid+1;
		}
		cout << n-l-(int)sqrt(n) << endl;
	}
	return 0;
}
posted @ 2025-03-13 14:52  lastxuans  阅读(8)  评论(0)    收藏  举报