关于ARC160的B只过了样例这件事
  • 板块学术版
  • 楼主wrkwrkwrk
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/5/14 22:27
  • 上次更新2023/10/23 15:42:11
查看原帖
关于ARC160的B只过了样例这件事
292748
wrkwrkwrk楼主2023/5/14 22:27

本人思路:
二次数论分块
对于每一个 1≤x≤n1\leq x\leq n ,求满足 1≤y,z≤nx1\leq y,z\leq \frac{n}{x} 且 yz≤nyz\leq n的个数并求和。
代码的时间复杂度似乎是O(Tnlog⁡(n))O(T\sqrt n\log(\sqrt n))的

#include<bits/stdc++.h>
#define MAX 0x3fffffffffffffffL
#define int long long
#define ipairs pair<int,int>
#define endl '\n'
#define mod 998244353
using namespace std;
int solve(int n,int m){
	int res=0;
	for(int l=1,r;l<=m;l=r+1){
		r=min(max(n/(n/l),n/m),m);
		res+=(r-l+1)*(min(n/l,m))%mod;
		res%=mod;
	}
	return res;
}
vector<int>b;
int solve_(int n,int m,int t){
	if(m*m<=n)return m*m%mod;
	int now=n;
	int u=2;
	int l=0,r=b.size();
	while(l+1<r){
		int mid=l+((r-l)>>1);//二分
		if(n/mid<=m)r=mid;
		else l=mid;
	}
	u=(l+1)*2;
	t=b[l];
	now=n/(l+1);
	for(int i=l+1;;i++){
		if(n/i<=m){
			return ((t-u*(now-m))%mod+mod)%mod;
		}else{
			t-=u*(now-n/i); 
			t=(t%mod+mod)%mod;
			now=n/i;
			u+=2;
		}
	} //求solve函数打表找规律
}
int solve2(int n){
	int res=0;
	int t=solve(n,n);
	int tt=t;
	int u=2;
	int now=n;
	for(int i=2;i*i<=n||(i<=n&&i<=10);i++){//防止b.size()=0
		b.push_back(tt);
		tt-=u*(now-n/i);
		tt=(tt%mod+mod)%mod;
		now=n/i;
		u+=2;
	}
	for(int l=1,r;l<=n;l=r+1){
		r=min(n/(n/l),n);
		res+=(r-l+1)*(solve_(n,n/l,t))%mod;
		res%=mod;
	}
	return res; 
}

signed main(){
	int t;
	cin>>t;
	while(t--){
		b.clear();
		int n;
		cin>>n;
		cout<<solve2(n)<<endl; 
	} 
	return 0;
}

结果,只过了样例....

只过了样例的链接

求调

2023/5/14 22:27
加载中...