这道题哪里用得着字典树嘛,直接判断,用string的函数不香嘛
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<cstdio> #include<queue> #include<map> #include<vector> #include<set> using namespace std; const int maxn=1e5+10; const int INF=0x3fffffff; typedef long long LL; typedef unsigned long long ull; /* int t,n,tot; int tri[maxn][12]; int isend[maxn]; char a[11]; bool insr(char *s){ int now=0,len=strlen(s); bool xx=0; for(int i=0;i<len;i++){ int x=s[i]-‘0‘; if(!tri[now][x]) tri[now][x]=++tot; now=tri[now][x]; //cout<<now<<" "; if(isend[now]) xx=1; } isend[now]++; // cout<<endl; if(xx) return 1; return 0; } bool flag; int main(){ scanf("%d",&t); while(t--){ scanf("%d",&n); memset(tri,0,sizeof(tri)); memset(isend,0,sizeof(isend)); flag=0; while(n--){ scanf("%s",a); if(insr(a)) flag=1; } if(flag) printf("NO\n"); else printf("YES\n"); } return 0; } */ //我的字典树为什么运行错误!!!! //不过这道题更见到的做法也很简单了 string ss[10010]; int t,n; bool flag; int main(){ cin>>t; while(t--){ cin>>n; for(int i=0;i<n;i++) cin>>ss[i]; sort(ss,ss+n); flag=0; for(int i=0;i<n-1;i++){ if(ss[i]==ss[i+1].substr(0,ss[i].length())) { flag=1; break; } } if(flag) cout<<"NO"<<endl; else cout<<"YES"<<endl; } return 0; }
异或的运算、01字典树,学会这类题目
//思路:把每一个数字 x 转化为31位的二进制数,不够的前面补0,并插入到字典树中(最低为二进制位为叶节点);
//接下来对每一个数字 x 的二进制位进行查找,每一步都尽量找与当前位置相反的数字进行访问,入如果有相反的数字,根据xor运算这一位就会留下一个 1 ,最后找出最大值就行。
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<cstdio> #include<queue> #include<map> #include<vector> #include<set> using namespace std; const int maxn=1e5+10; const int INF=0x3fffffff; typedef long long LL; typedef unsigned long long ull; //思路:把每一个数字 x 转化为31位的二进制数,不够的前面补0,并插入到字典树中(最低为二进制位为叶节点); //接下来对每一个数字 x 的二进制位进行查找,每一步都尽量找与当前位置相反的数字进行访问,入如果有相反的数字,根据xor运算这一位就会留下一个 1 ,最后找出最大值就行。 int trie[maxn*32][2]; int n,ans; void inti(){ memset(trie,0,sizeof(trie)); ans=1; } void inse(int x){ int now=1; for(int i=30;i>=0;i--){ int c=x&(1<<i)?1:0; if(!trie[now][c]){ trie[now][c]=++ans; } now=trie[now][c]; } } int que(int x){ int now=1; int tot=0; for(int i=30;i>=0;i--){ int c=x&(1<<i)?1:0; if(trie[now][!c]){ now=trie[now][!c]; tot|=(1<<i); } else now=trie[now][c]; } return tot; } int main(){ inti(); scanf("%d",&n); int x,maxx=0; for(int i=0;i<n;i++){ scanf("%d",&x); inse(x); maxx=max(maxx,que(x)); } printf("%d\n",maxx); return 0; }
求两段不相交的连续异或和最大值,就是要处理出异或前缀和,不断加入01Trie树求解即可。
虑到要求两个子段,用ls[i],rs[i分别表示1~i、i~n的最大异或子段,最后扫一遍取max即可。
//原文链接:https://blog.csdn.net/Jason_lxy/article/details/88855100
//重点就是要枚举每一个点左右边的最大异或和
//另一种做法:不太懂 https://blog.csdn.net/bao___zi/article/details/83092217,过不了两个点》。。。。y一个是内存超限,一个是运行错误
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<cstdio> #include<queue> #include<map> #include<vector> #include<set> using namespace std; const int maxn=4e5+10; const int INF=0x3fffffff; typedef long long LL; typedef unsigned long long ull; //所以处理出异或前缀和,不断加入01Trie树求解即可。 //考虑到要求两个子段,用ls[i],rs[i分别表示1~i、i~n的最大异或子段,最后扫一遍取max即可。 //原文链接:https://blog.csdn.net/Jason_lxy/article/details/88855100 //重点就是要枚举每一个点左右边的最大异或和 //另一种做法:不太懂 https://blog.csdn.net/bao___zi/article/details/83092217 //过不了两个点》。。。。y一个是内存超限,一个是运行错误 int ch[12500000][2]; int lf[maxn],ri[maxn]; int n,a[maxn]; int tot=1; inline int read(){ int ret=0,ff=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘) ff=-1;ch=getchar();} while(isdigit(ch)){ret=(ret<<3)+(ret<<1)+(ch^48);ch=getchar();} return ret*ff; } inline void inti(){ memset(ch,0,sizeof(ch)); tot=1; } inline void inse(int x){ int now=1; for(int i=30;i>=0;i--){ int c=x&(1<<i)?1:0; if(!ch[now][c]) ch[now][c]=++tot; now=ch[now][c]; } } inline int fin(int x){ int now=1,ans=0; for(int i=30;i>=0;i--){ int c=x&(1<<i)?1:0; if(ch[now][!c]){ now=ch[now][!c]; ans|=(1<<i); } else now=ch[now][c]; } return ans; } int main(){ n=read(); for(int i=1;i<=n;i++){ a[i]=read(); } lf[1]=a[1]; inse(a[1]); for(int i=2;i<=n;i++){ lf[i]=max(lf[i-1],fin(a[i])); //前缀异或和 inse(a[i]); } inti(); ri[n]=a[n]; inse(a[n]); for(int i=n-1;i>=2;i--){ ri[i]=max(ri[i+1],fin(a[i])); //fin(a[i])表示的其实是通过a[i]异或能够得到的最大值 //而ri[i+1]就是表示不需要用a[i] 去异或 inse(a[i]); } int maxx=0; for(int i=1;i<=n-1;i++){ maxx=max(maxx,lf[i]+ri[i+1]); } printf("%d\n",maxx); return 0; }
原文:https://www.cnblogs.com/shirlybaby/p/12732644.html