Luogu7738

引言

同步赛,大常数选手卡常题过了!感动!

看到这题——az,什么字符串神仙题?01-Trie 上自动机?

看到 gen.cpp,笑了,字典是随机的,因此我们可以考虑乱搞。

说句闲话,有没有人强制离线过的?很好奇。

思路

注意到 \(k\le15\),因此我们如果把长为 \(256\) 的串均分 \(16\) 块,每块长为 \(16\),那么噪音干扰位(不匹配位)最多只会在其中 \(15\) 块中,因此必然会有一块是全匹配的。

对每一块,我们考虑,其状态不会超过 \(65536\) 种,而字典大致随机均分其中,每种情况有 \(\dfrac{400000}{65536}\approx6\) 的单词满足。

于是把字典中的每种情况插进一个 vector 表中,每次暴力查表,查到即有解,否则无解。

判断时可能要 bitset 的异或与 count 等,建议手写一个,避免卡常。

复杂度分析

时空分析

为了更直观,我们把常数写进时间复杂度记号中。

预处理(包括 count 预处理)约 \(O(256n+16n+65536)\)

单次询问约 \(O(16\times6\times\frac{256}{w})\),手写的话 \(w\)\(64\)

因为又要异或又要 count,可能还有一个 \(2\) 的常数得乘上。

空间的话稍微证一下是会发现不会爆的。

代码难度分析

还好吧(?),反正是我同步赛唯一做出的题(到时候被不被少爷机卡常就不知道了)。

上代码。

#include <stdio.h>
#include <vector>
typedef long long llt;
typedef unsigned short usint;
typedef unsigned uint;typedef unsigned long long ullt;
typedef bool bol;typedef char chr;typedef void voi;
typedef double dbl;
template<typename T>bol _max(T&a,T b){return(a<b)?a=b,true:false;}
template<typename T>bol _min(T&a,T b){return(b<a)?a=b,true:false;}
template<typename T>T power(T base,T index,T mod){return((index<=1)?(index?base:1):(power(base*base%mod,index>>1,mod)*power(base,index&1,mod)))%mod;}
template<typename T>T lowbit(T n){return n&-n;}
template<typename T>T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<typename T>T lcm(T a,T b){return(a!=0||b!=0)?a/gcd(a,b)*b:(T)0;}
const uint N = 400000;bol s[N+1][265];
ullt myRand(ullt &k1,ullt &k2){ullt k3=k1,k4=k2;k1=k4;k3^=(k3<<23);k2=k3^k4^(k3>>17)^(k4>>26);return k2+k4;}
voi gen(uint n,ullt a1,ullt a2){for(uint i=0;i<n;i++)for(uint j=0;j<256;j++)s[i][j]=(myRand(a1,a2)&(1ull<<32))?1:0;}
usint Count[66005];ullt Turn[150];
struct my_bitset
{
	ullt A,B,C,D;
	my_bitset():A(0),B(0),C(0),D(0){}
	my_bitset(bol*T){A=B=C=D=0;for(uint i=0;i<64;i++)A=(A<<1)|T[i];for(uint i=64;i<128;i++)B=(B<<1)|T[i];for(uint i=128;i<192;i++)C=(C<<1)|T[i];for(uint i=192;i<256;i++)D=(D<<1)|T[i];}
	my_bitset(chr*T)
	{
		A=B=C=D=0;
		for(uint i=0;i<16;i++)A=(A<<4)|Turn[(uint)T[i]];for(uint i=16;i<32;i++)B=(B<<4)|Turn[(uint)T[i]];
		for(uint i=32;i<48;i++)C=(C<<4)|Turn[(uint)T[i]];for(uint i=48;i<64;i++)D=(D<<4)|Turn[(uint)T[i]];
	}
	usint get(uint p){return((p<8)?((p<4)?(D>>(p<<4)):(C>>((p&3)<<4))):((p<12)?(B>>((p&3)<<4)):(A>>((p&3)<<4))))&65535;}
	my_bitset operator^(my_bitset b){return b.A^=A,b.B^=B,b.C^=C,b.D^=D,b;}
	voi chg(){A=~A,B=~B,C=~C,D=~D;}
	usint count()
	{
		return
			Count[A&65535]+Count[(A>>16)&65535]+Count[(A>>32)&65535]+Count[(A>>48)&65535]+Count[B&65535]+Count[(B>>16)&65535]+Count[(B>>32)&65535]+Count[(B>>48)&65535]+
			Count[C&65535]+Count[(C>>16)&65535]+Count[(C>>32)&65535]+Count[(C>>48)&65535]+Count[D&65535]+Count[(D>>16)&65535]+Count[(D>>32)&65535]+Count[(D>>48)&65535];
	}
};
my_bitset B[400005],Q;
std::vector<uint>V[25][66005];
chr C[105];
int main()
{
	for(usint i=1;i;i++)Count[i]=Count[i>>1]+(i&1);
	uint n,m,k;ullt a1,a2;bol ok=false;scanf("%u%u%llu%llu",&n,&m,&a1,&a2),gen(n,a1,a2);
	for(uint i=0;i<n;i++){B[i]=s[i];for(uint j=0;j<16;j++)V[j][B[i].get(j)].push_back(i);}
	for(uint i=0;i<10;i++)Turn[i+'0']=i;
	for(uint i=0;i<6;i++)Turn[i+'A']=10+i;
	while(m--)
	{
		scanf("%s%u",C,&k),Q=my_bitset(C);
		if(ok)Q.chg(),ok=false;
		for(uint i=0;i<16&&!ok;i++)
		{
			std::vector<uint>&W=V[i][Q.get(i)];
			for(uint p=W.size()-1;~p;p--)if((B[W[p]]^Q).count()<=k){ok=true;break;}
		}
		puts(ok?"1":"0");
	}
	return 0;
}

后记

谔,希望不要有卡常题了QAQ

放张图,参见

posted @ 2022-02-14 07:22  myee  阅读(49)  评论(0编辑  收藏  举报