CF1704G
令 \(A_i=a_i+2a_{i-1}+a_{i-2},B_i=b_i-2b_{i-1}+b_{i-2}\),然后可以发现对于任意位置 \(i\) 进行操作,除了 \(A_{i}\) 将会变成 \(A_i+1\),其他位置的数值均不变。因此对 \(a\) 的操作,对 \(A\) 即单点操作。
可以发现,以下条件等同于 \(b[1,m]\) 可以与 \(a[k+1,k+m]\) 匹配。
对于 \(i\le k+2\),对于 \(i\) 位置的操作有 \(a_{k+1}+a_{k+2}\leftarrow a_{k+1}+a_{k+2}+(-1)^{k-i}\)。因此第二个条件限制了前 \(k+2\) 位置间奇数位置和偶数位置之间操作次数差异。当对 \(i\) 进行操作时,\(a_{k+1}\leftarrow a_{k+1}+(k-i+2)\times (-1)^{k-i}\)。
于是问题就转化成了使用 \(-0,+1,-2,\cdots,(-1)^nn\) 让减法操作次数(使 \(a_{k+1}\) 减小的操作)减去加法操作次数为 \(a\),并且最后的 \(a_{k+1}\) 应该为 \(b\)。
然后可以观察在某个位置进行一次操作后,\(i\) 及 \(i+1\) 位置上的数字变化(设其分别为 \(x,y\))。
为了方便可以先把所有减法操作做了,之后再撤销(重新添加,即这样均变成加法操作)。这样就得到 \(a_{i}+a_{i+1}\) 等于什么,然后就得到了 \(x+y,x\) 等于多少,然后前两个条件就可以转化成:\(a\leftarrow a+\lfloor\frac{k+1}{2}\rfloor+1,b\leftarrow b+\sum\limits_{i=0}^{\lfloor\frac{k+1}{2}\rfloor} 2i\) 其中 \(a\) 表示需要选择 \(a\) 个(即 \(x+y\)),\(b\) 表示选择的和是 \(b\)(即 \(x\))。
所有满足 \(\sum\limits_{i=0}^{a-1} i\le b\le \sum\limits_{i=k+1-a}^{k+1}\) 的 \(b\) 都是合法且容易构造出来的。
然后考虑第三个条件,构造函数 \(f(k)=\sum\limits_{i=3}^m (B_i-A_{i+k})(B_i-A_{i+k}-1)\)。显然 \(B_i=A_{i+k}\) 或 \(B_i=A_{i+k}+1\) 时上式为 \(0\)。而 \(B_i\) 是否等于 \(A_{i+k}\) 代表着我们是否要对 \(i+k\) 位置进行操作,即 \(B_i=A_{i+k}\) 时不需要操作,\(B_i=A_{i+k}+1\) 时进行一次操作, 否则上式一定 \(>0\)。并且可以发现 \(b[1,m]\) 可以与 \(a[k+1,k+m]\) 匹配上时一定有 \(f(k)=0\)。考虑如何计算 \(f\)。
对于 \(A_{i+k}B_i\),这是一个卷积形式,可以转化为多项式乘法,使用 FFT 求解,而其他项显然是可以简单求出的。
考虑到 \(f(k)\) 的值很大,如果使用 NTT,可能需要测试几个不同的素数来避免 hack,这部分时间复杂为 \(\mathcal O(n\log n)\)。
并且可以通过 bitset 来找到满足第三个条件的 \(k\),时间复杂度为 \(\mathcal O(\frac{n^2}{\omega})\)
#include<bits/stdc++.h>
#define ll long long
#define qwq printf("qwq\n");
#define R(i,a,b) for(int i=(a),i##E=(b);i<=i##E;i++)
#define L(i,a,b) for(int i=(b),i##E=(a);i>=i##E;i--)
using namespace std;
const int mod=998244353;
const int _G=646;
const int invG=208611436;
const int G_pw=1<<20;
inline int fix(int a,int p=mod)
{
	a=(a%p+p)%p;
	return a;
}
inline int add(int a,int b,int p=mod)
{
	a+=b;
	if(a>=p) a-=p;
	return a; 
}
inline int dec(int a,int b,int p=mod)
{
	a-=b;
	if(a<0) a+=p;
	return a;
}
inline int mul(int a,int b,int p=mod)
{
	ll c=1ll*a*b%mod;
	return fix(c,p);
}
inline int fpow(int a,int b=mod-2,int p=mod)
{
	int ret=1;
	while(b)
	{
		if(b&1) ret=mul(ret,a,p);
		a=mul(a,a,p);
		b>>=1;
	}
	return ret;
}
inline ll calc(ll l,ll r,ll k)
{
	if(r<l) return 0;
	ll t=(r-l)/k+1;
	ll tmp=1ll*l*t+t*(t-1)/2*k;
	return tmp;
}
inline ll get_mn(ll a,ll b)
{
	b=(a+1)/2-b;
	return calc(1,a,2)-calc(a-b+1,a,1);
}
inline ll get_mx(ll a,ll b)
{
	b=(a+1)/2-b;
	return calc(1,a,2)-calc(1,b,1);
}
struct fu
{
	void NTT(vector<ll>&a,bool rev)
	{
		int n=(int)a.size();
		for(int i=1,j=0;i<n;i++)
		{
			int bit=n>>1;
			for(;j>=bit;bit>>=1) j-=bit;
			j+=bit;
			if(i<j) swap(a[i],a[j]);
		}
		for(int len=2;len<=n;len<<=1)
		{
			int tG=rev?invG:_G;
			for(int i=len;i<G_pw;i<<=1) tG=1ll*tG*tG%mod;
			for(int i=0;i<n;i+=len)
			{
				int w=1;
				for(int j=0;j<len/2;j++)
				{
					int u=a[i+j],v=mul(a[i+j+len/2],w);
					a[i+j]=add(u,v);
					a[i+j+len/2]=dec(u,v);
					w=mul(w,tG);
				}
			}
		}
		if(rev)
		{
			int invn=fpow(n);
			//cout<<invn<<endl;
			R(i,0,n-1) a[i]=mul(a[i],invn);
		}
	}
	vector<ll>poly_mult(vector<ll>a,vector<ll>b)
	{
		int t=(int)(a.size()+b.size());
		int tt=1;
		while(tt<t) tt<<=1;
		vector<ll>c(tt);
		a.resize(tt),b.resize(tt);
		// cout<<"NTT:"<<endl;
		// for(auto x:a) cout<<x<<" ";
		// cout<<endl;
		NTT(a,0),NTT(b,0);
		R(i,0,tt-1) c[i]=mul(a[i],b[i]);
		NTT(c,1);
		return c;
	}
};
int n,m;
bitset<200010>vis;
void solve()
{
	vis.reset();
	cin>>n;
	vector<ll>a(n);
	R(i,0,n-1) cin>>a[i];
	cin>>m;
	vector<ll>b(m);
	R(i,0,m-1) cin>>b[i];
	if(m>2)
	{
		vector<ll>A(n-2),B(m-2),c;
		R(i,0,n-2-1) A[i]=a[i]+2*a[i+1]+a[i+2],c.emplace_back(A[i]);
		R(i,0,m-2-1) B[i]=b[i]+2*b[i+1]+b[i+2],c.emplace_back(B[i]),c.emplace_back(B[i]+1);
		reverse(B.begin(),B.end());
		sort(c.begin(),c.end());
		c.resize(unique(c.begin(),c.end())-c.begin());
		for(ll &x:A) x=lower_bound(c.begin(),c.end(),x)-c.begin()+1;
		for(ll &x:B) x=lower_bound(c.begin(),c.end(),x)-c.begin()+1;
		fu f;
		auto C=f.poly_mult(A,B);
		// for(auto x:C) cout<<x<<" ";
		// cout<<endl; 
		ll s=0;
		R(i,0,m-2-1) s=add(s,mul(A[i],A[i]+1)),s=add(s,mul(B[i],B[i]-1));
		R(i,0,n-m)
		{
			int p=m+i-3;
			if(s!=add(C[p],C[p])) vis[i]=1;
			s=dec(s,mul(A[i],A[i]+1));
			if(i<n-m) s=add(s,mul(A[i+m-2],A[i+m-2]+1));
		}
	}
	R(i,0,n-m) if(!vis[i])
	{
		R(j,0,1)
		{
			ll t=a[i]+a[i+1]-b[0]-b[1]+j;
			if(t>(i+2)/2) continue;
			if(t<-(i+1)/2) continue;
			if(a[i]+get_mn(i+1,t)>b[0]) continue;
			if(a[i]+get_mx(i+1,t)<b[0]) continue;
			R(k,0,m-2-1) if(a[i+k]+2*a[i+k+1]+a[i+k+2]!=b[k]+2*b[k+1]+b[k+2]&&a[i+k]+2*a[i+k+1]+a[i+k+2]+1!=b[k]+2*b[k+1]+b[k+2])
			{
				vis[i]=1;
			}
			if(vis[i]) continue;
			vector<int>ans;
			if(j) ans.emplace_back(i+1);
			R(k,0,m-2-1) if(a[i+k]+2*a[i+k+1]+a[i+k+2]!=b[k]+2*b[k+1]+b[k+2])
			{
				ans.emplace_back(i+k+2);
			}
			ll ddd=b[0]-a[i];
			for(int k=i+1;k>=1;k--)
			{
				ll dc=((k&1)?k:-k),dd=((k&1)?1:-1);
				if(get_mn(k-1,t)<=ddd&&ddd<=get_mx(k-1,t))
				{
				}
				else
				{
					ans.emplace_back(i-k+1);
					ddd-=dc,t-=dd;
				}
			}
			cout<<ans.size()<<'\n';
			for(int x:ans) cout<<x+1<<' ';
			cout<<endl;
			return;
		}
	}
	cout<<-1<<endl;
}	
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	int _;
	cin>>_;
	while(_--) solve();
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号