2021.3.26 正睿憨批赛

2021.3.26 正睿憨批赛

为什么称之为憨批赛呢?因为在这场比赛中,我发现了自己憨逼的本质

"一个对着错误类欧敲了一个上午的人如果还不是憨批,那么只有不仅敲了一个上午假类欧,还在最后改成皮克定理的人才是憨批" ——沃兹基·硕德

T1

题意:定义函数\(f_k:a\rightarrow b\),其中\(\forall i\in[0,n-1],b_i={\Large\oplus}_{j=0}^{k-1}a_{(i+k)\%n}\)

\(f_{k,0}(x)=f_k(x),f_{k,i}(x)=f_k(f_{k,i-1}(x))\)

\(f_{k,T}(a)\).

\(|a|=n\leq 5\times 10^5,T\leq 10^{18},a_i\leq 10^9\)

不难发现异或卷积等价于值域对位模2意义下卷积(下文均为模2意义下)

转换为\(a*(1+x+x^2+\cdots+x^{k-1})^T \equiv b \pmod {x^n-1}\)

不难想到\(O(n\log_2^2n)\)\(\tt NTT+quickpow\)

但是显然会\(\rm TLE\)

考虑特殊性质

不难证明\((1+x+x^2+\cdots+x^{k-1})^{2^\omega}\equiv 1+x^{2^\omega}+x^{2\cdot2^\omega}+\cdots+x^{(k-1)2^\omega}\pmod {x^n-1}\)

证明:令\(g(x)=\sum_{i=0}^{k-1}x^i\),求证命题\(g(x)^{2^\omega}=g(x^{2^\omega})\)

  1. \(\omega=1\)

    \[g(x)^2=(1+x^2+x^4+\cdots+x^{2(k-1)})+2\sum_{i,j\in[0,k-1],i\not =j}x^ix^j\\ =1+x^2+x^4+\cdots+x^{2(k-1)}\\ =g(x^2) \]

  2. \(\omega > 1\)时,当\(x< \omega\)时成立

    \[g(x)^{2^\omega}=(g(x)^{2^{\omega-1}})^2\\ =g(x^{2^{\omega-1}})^2\\ =g(x^{2^\omega}) \]

    \(\rm Q.E.D\)

所以我们先对\(T\)二进制分解,每次对分解出的\(\lambda\)提取出置换(下式模\(n\))\(\left(\begin{matrix}0&1&2&\cdots& n-1\\2^\lambda&1+2^\lambda&2+2^\lambda&\cdots&n-1+2^\lambda\end{matrix}\right)\)

的每个循环单独进行转移

时间复杂度为\(O(n\log_2T)\)

#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
	T t=0;char k;bool vis=0;
	do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
	while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
	return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
int a[500005],b[500005];
bool vis[500005];
vector<int>tem;
int main(){
	int s=read,m=read;ll T=read;
	for(int i=0;i<s;++i)a[i]=read;
	for(ll k=1;T;k<<=1)
		if(T&k){
			T^=k;int x=k%s;
			memset(vis,0,s);
			memcpy(b,a,s<<2);
			for(int i=0;i<s;++i)
				if(!vis[i]){tem.clear();
					int ans=0,S=0,r=0;
					for(int j=i;!vis[j];j=(j+x)%s)
						tem.push_back(j),S^=b[j],vis[j]=1;
					if((m/tem.size())&1)ans=S;
					r=m%tem.size();
					for(int j=0;j!=r;j=(j+1)%tem.size())
						ans^=b[tem[j]];
					for(int j=0;j<tem.size();++j){
						a[tem[j]]=ans;
						ans^=b[tem[j]];
						ans^=b[tem[(j+m)%tem.size()]];
					}
				}
		}
	for(int i=0;i<s;++i)printf("%d ",a[i]);
	return 0;
}

T2

\(\sum_{i=0}^n\sum_{j=0}^\infty [j\leq i\sqrt{p\over q}]\),共\(T\)

\(T\in[1,10^5].p,q\in[1,1000],n\in[1,10^9]\)

如果没有根号,那就是一个简单的类欧

可是有根号

所以我们考虑使用一个有理数\(\xi\)去拟合这个无理数\(\psi\)(也可能是有理数)

首先需要满足\(\forall x\in [1,n],\lfloor i\psi\rfloor =\lfloor i\xi\rfloor\)

其次分子与分母不能太大,不能超过\(\tt longlong\)(其实也可以超过,如果你不嫌难打,也不怕\(\rm T\))

所以我们考虑在\(\tt Stern-Brocot-Tree\)上进行逼近

其实可以树上倍增加判定,时间复杂度为\(O(\log_2q\log_2\log_2q)\)

其实暴力跳也是可以的,如果特判掉\(\frac{p}{q}=\xi^2\)的情况,因为一般情况下期望时间复杂度为\(\log_2q\),但是有理数会被卡

#include<bits/stdc++.h>
using namespace std;
# define ll long long
# define read read1<ll>()
# define Type template<typename T>
Type T read1(){
	T t=0;char k;bool vis=0;
	do (k=getchar())=='-'&&(vis=1);while('0'>k||k>'9');
	while('0'<=k&&k<='9')t=(t<<3)+(t<<1)+(k^'0'),k=getchar();
	return vis?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
int cnt;
void pr(__int128 x){
	if(x<10)putchar(x+'0');
	else pr(x/10),putchar(x%10+'0');
}
pair<ll,ll> query(pair<ll,ll>W,pair<ll,ll>x,pair<ll,ll>y,pair<ll,ll>z){
	if(y.second>=1e17||y.first>=1e17)return x;
	if((__int128)W.first*y.second*y.second<(__int128)W.second*y.first*y.first)
		return query(W,x,make_pair(x.first+y.first,x.second+y.second),y);
	return query(W,y,make_pair(y.first+z.first,y.second+z.second),z);
}
__int128 query(ll p,ll q,ll b,ll n){
	if(!p)return 0;//cout<<p<<' '<<q<<' '<<n<<endl;
	if(p>=q||b>=q)return (__int128)p/q*n*(n+1)/2+(__int128)b/q*(n+1)+query(p%q,q,b%q,n);
	__int128 m=(__int128)p*n+b;m/=q;
	return m*n-query(q,p,q-b-1,m-1);
}
int main(){//fre("ex_B3");
	for(int T=read;T--;){
		ll p=read,q=read,n=read;
		ll v=__gcd(p,q);p/=v;q/=v;
		pair<ll,ll>t;
		if((ll)sqrt(p)*(ll)sqrt(p)==p&&(ll)sqrt(q)*(ll)sqrt(q)==q)t=make_pair(sqrt(p),sqrt(q));
		else t=query(make_pair(p,q),make_pair(0,1),make_pair(1,1),make_pair(1,0));
		pr(query(t.first,t.second,0,n)+n+1);putchar('\n');
		cnt=0;
	} 
	return 0;
}


posted @ 2021-03-26 21:46  ファイナル  阅读(66)  评论(0)    收藏  举报