1 条题解
-
1
意识流题解,学习可以参照其他题解,此题解仅思考过程。
或者直接看代码。
显然出题人给你个老长的字符串压位了信息,可见这题要超级高效地解决才行。
于是首先先把四个四个四个压位出来的值离散化。
然后“基因比较”就变成了数字匹配。
注意到本题中 ,,数据随机。
考虑 Hash。
把值域按 分块,则在数据完全随机且较大时,有较大概率,会出现某几块同源虫都存在的现象。
于是直接暴力枚举每个块内匹配。
然后暴力匹配判断,成功率会有增加。
然后你发现假了。
改一改。
把值域按 分块,则在数据完全随机且较大时,有较大概率,会出现某 块同源虫都存在的现象。
对每个数,仅保留前 块。
于是直接暴力枚举每个块内匹配。
这个东西就正确了。
但复杂度点名被卡了。
匹配复杂度是 的?
似乎无法优化了?
询问是 组的?
似乎也无法优化了?
因此我们要做到平均 分配。
考虑最开始那种方法。
改为分成 块,其中必有某块匹配了至少两个。
暴力枚举是哪块,再枚举是哪两个,就好了。
可以证明,此时复杂度得到保障。
Code
为了方便,这里改为分成 块。这样成功率仍旧很高。
#include <algorithm> #include <random> #include <stdio.h> #include <vector> typedef long long llt; 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 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;} template<typename T>T exgcd(T a,T b,T&x,T&y){if(b!=0){T ans=exgcd(b,a%b,y,x);y-=a/b*x;return ans;}else return y=0,x=1,a;} template<typename T>T power(T base,T index,T mod) { T ans=1%mod; while(index) { if(index&1)ans=ans*base%mod; base=base*base%mod,index>>=1; } return ans; } typedef unsigned short u16; namespace Turn { std::vector<std::pair<u16,u16> >Map[70005];u16 cnt; u16 get(uint v){ u16 u=v>>16,d=v&65535; for(auto s:Map[u])if(s.first==d)return s.second; return Map[u].push_back({d,cnt}),cnt++; } uint turn(chr*c){return(uint)c[0]<<24|(uint)c[1]<<16|(uint)c[2]<<8|(uint)c[3];} } chr C[20000005];u16 Info[40005][135]; bol Gone[40005];uint Another[40005],l; bol check(uint u,uint v) { if(u==v)return false; static uint User[265];std::merge(Info[u],Info[u]+l,Info[v],Info[v]+l,User); uint ans=0;for(uint i=1;i<l*2;i++)ans+=User[i-1]==User[i]; return ans==l/2; } uint R[40005]; std::vector<uint>A[265][265]; int main() { #ifdef MYEE freopen("QAQ.in","r",stdin); // freopen("QAQ.out","w",stdout); #endif uint n,m;scanf("%u%u%u%s",&n,&m,&l,C); for(uint i=0;i<n*2;i++)for(uint j=0;j<l;j++)Info[i][j]=Turn::get(Turn::turn(C+((i*l+j)<<2))); for(uint i=0;i<n*2;i++)std::sort(Info[i],Info[i]+l); for(uint i=0;i<l/2;i++) { for(uint j=0;j<l*2;j++)for(uint k=j+1;k<l*2;k++)A[j][k].clear(); for(uint j=0;j<n*2;j++)if(!Gone[j]) { uint a=R[j];uint&r=R[j];while(r<l&&Info[j][r]<(i+1)*l*2)r++; while(a<r) { for(uint k=a+1;k<r;k++)A[Info[j][a]%(l*2)][Info[j][k]%(l*2)].push_back(j); a++; } } for(uint j=0;j<l*2;j++)for(uint k=j+1;k<l*2;k++) for(auto x:A[j][k])if(!Gone[x])for(auto y:A[j][k])if(!Gone[y]&&check(x,y)) { Gone[x]=Gone[y]=true,Another[x]=y,Another[y]=x;break; } } for(uint x=0;x<n*2;x++)if(!Gone[x])for(uint y=x+1;y<n*2;y++)if(!Gone[y]&&check(x,y)) { Gone[x]=Gone[y]=true,Another[x]=y,Another[y]=x;break; } for(uint i=0;i<n*2;i++)printf("%u\n",Another[i]+1); return 0; }
- 1
信息
- ID
- 3820
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 3
- 已通过
- 2
- 上传者