1. 程式人生 > 其它 >noip模擬26

noip模擬26

T1 神炎皇 T2 降雷皇 T3 幻魔皇

期望得分:60+100+40=200
實際得分:60+100+40=200

T1 整個\(O(n^2)\)的就20了,然後因為時間沒到,就接著推,還有打表。
然後發現,gcd(a,b)=d時, a=xd , b=yd ,想要滿足 \((a+b)|ab,即(x+y)d|xyd^2\),需要滿足 \((x+y)|d\)
然後設 (x+y)k=d,那麼使 \((x+y)^2k\),滿足小於n就行了,答案就是 \(\frac{n}{{(x+y)}^2}\)
這個的複雜度是 \(O(n^2 \sqrt n)\),但是列舉到對答案沒有貢獻 break 掉就行了,準確是在 \(x+y=\sqrt n\),這個時候60pts。
其實不用列舉,因為大小相等的(x+y)對答案的貢獻都一樣,並且若 x,y互質,那麼x,y和(x+y)也互質,設 x+y=k ,對數就是 \(\phi(k)\)

,線性篩尤拉函式,篩到\(\sqrt n\),複雜度\(O(\sqrt n)\)

T2 權值線段樹維護最長長度和其數量,單點修改,區間查詢

T3 求樹上距離,找lca,只有兩種情況,lca為兩個白點中的一個,或者是一個黑的。第一種情況,列舉所有長度,在深度合法的白色節點向下找 i 步。第二種情況,因為有兩顆子樹,那就在深度合法的黑色節點向下分別找 i和 j步

T1

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+11;
long long n;
int sl;
long long phi[N],p[N];
bool fp[N];
void oula()
{
	long long ss=sqrt(n);
	fp[0]=1;
	fp[1]=1;
	for(int i=2;i<=ss;i++)
	{
		if(!fp[i])
		{
			phi[i]=i-1;
			p[++sl]=i;
		}
		for(int j=1;j<=sl&&p[j]*i<=ss;j++)
		{
			fp[i*p[j]]=1;
			if(i%p[j]==0)
			{
				phi[i*p[j]]=phi[i]*p[j];
				break;
			}
			else
				phi[i*p[j]]=phi[i]*(p[j]-1);
		}
	}
	return;
}
int main()
{
	cin>>n;
	oula();
	long long ans=0;
	int k=sqrt(n);
	for(long long i=1;i<=k;i++)
		ans+=phi[i]*(n/(i*i));
	printf("%lld\n",ans);
	return 0;
}

T2

#include<bits/stdc++.h>
using namespace std;
const int N=100011;
const long long mod=123456789;
struct tree{
	int l,r;
	int len;
	long long num;
}tre[5*N];
int n,ty;
int xl[N],lsh[N];
inline int read()
{
	int s=0;
	int w=1;
	char ch=getchar();
	while(ch>'9'||ch<'0')
	{
		if(ch=='-')
			w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s*w;
}
void build(int i,int l,int r)
{
	tre[i].l=l;
	tre[i].r=r;
	if(l==r)
		return;
	int mid=(l+r)>>1;
	build(i<<1,l,mid);
	build(i<<1|1,mid+1,r);
	return;
}
void updata(int i)
{
	if(tre[i<<1].len==tre[i<<1|1].len)
	{
		tre[i].num=tre[i<<1].num+tre[i<<1|1].num;
		tre[i].num%=mod;
		tre[i].len=tre[i<<1].len;
	}
	else
	{
		if(tre[i<<1].len>tre[i<<1|1].len)
		{
			tre[i].len=tre[i<<1].len;
			tre[i].num=tre[i<<1].num;
		}
		else
		{
			tre[i].len=tre[i<<1|1].len;
			tre[i].num=tre[i<<1|1].num;
		}
	}
	return;
}
tree query(int i,int x)
{
	tree ans1,ans2;
	ans2.len=ans1.len=0;
	ans2.num=ans1.num=0;
	if(tre[i].l==tre[i].r)
	{
		if(tre[i].l<=x)
			return tre[i];
		return ans1;
	}
	if(tre[i].r<=x)
		return tre[i];
	else
	{
		int mid=(tre[i].l+tre[i].r)>>1;
		if(mid+1>x)
			return query(i<<1,x);
		else
		{
			ans1=query(i<<1,x);
			ans2=query(i<<1|1,x);
			if(ans1.len==ans2.len)
			{
				ans1.num+=ans2.num;
				ans1.num%=mod;
				return ans1;
			}
			else
			{
				if(ans1.len>ans2.len)
					return ans1;
				else
					return ans2;
			}
		}
		
	}
	return ans1;
}
void insert(int i,int x,tree ans)
{
	if(tre[i].l==tre[i].r)
	{
		if(x==tre[i].l)
		{
			if(!ans.num)
				ans.num++;
			if(tre[i].len==ans.len)
				ans.num+=tre[i].num;
			tre[i].num=ans.num;
			tre[i].num%=mod;
			tre[i].len=ans.len;
			
		}
		return;
	}
	int mid=(tre[i].l+tre[i].r)>>1;
	if(mid>=x)
		insert(i<<1,x,ans);
	else
		insert(i<<1|1,x,ans);
	updata(i);
	return;
}
void lsh_()
{
	sort(lsh+1,lsh+n+1);
	int x=unique(lsh+1,lsh+n+1)-lsh;
	for(int i=1;i<=n;i++)
		xl[i]=lower_bound(lsh+1,lsh+x,xl[i])-lsh;
	return;
}
int main()
{
	n=read();
	ty=read();
	for(int i=1;i<=n;i++)
		lsh[i]=xl[i]=read();
	lsh_();
	build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		tree ans=query(1,xl[i]-1);
		ans.len++;
		insert(1,xl[i],ans);
	}
	cout<<tre[1].len<<endl;
	if(ty)
		cout<<tre[1].num%mod<<endl;
	return 0;
}

T3

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=100011;
const int mod=123456789;
int n;
int f[N];
int sum[N];
int ans[N];
void pre()
{
	f[1]=f[2]=1;
	sum[1]=1;
	sum[2]=2;
	for(int i=3;i<=n;i++)
	{
		f[i]=(f[i-1]+f[i-2])%mod;
		sum[i]=(sum[i-1]+f[i])%mod;
	}
	return;
}
signed main()
{
	cin>>n;
	pre();
	for(int i=2;i<n-1;i++)
		ans[i]=f[i-1]*(sum[n-i-2]+1)%mod;
	ans[n-1]=f[n-2];
	for(int i=2;i<n;i++)
	{
		for(int j=3;j<n;j++)
			ans[i+j]=(ans[i+j]+sum[n-max(i,j)-1]*f[i-1]%mod*f[j-2])%mod;
		ans[i+1]=(ans[i+1]+sum[n-i-1]*f[i-1]%mod)%mod;
	}
	for(int i=1;i<=2*n;i++)
		printf("%lld ",ans[i]);
	return 0;
}