race\牛客\多校\广西师范大学训练赛\雾锁山头山锁雾.cpp
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
#include<array>
using namespace std;#define endl '\n'#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define int long long
#define int128 __int128_t
#define ll long long
#define ld long double
typedef unsigned long long ull ;
#define fr(i,l,r) for(int i=l;i<=r;i++)
#define fer(i,x) for(int i=e.head[x];i;i=e.next[i])
#define ufr(i,n,z) for(int i = n;i >= z; i--)
#define pb(x) push_back(x)
#define all(a) a.begin(),a.end()
#define fi first
#define se second
typedef pair<int,int> pr;
const int N = 1e6+10;
const int mod=998244353,inf=1e18;
//hash板子
typedef pair<int,int> hashv;
const static int Mod1 = 1000000033;
const static int Mod2 = 1000000103;
const static hashv bas = make_pair(10331,100313);
hashv operator+ (const hashv &a,const hashv &b)
{int c1 = a.first + b.first,c2 = a.second + b.second;if(c1 >= Mod1) c1 -= Mod1;if(c2 >= Mod2) c2 -= Mod2;return make_pair(c1,c2);
}hashv operator- (const hashv &a,const hashv &b)
{int c1 = a.first - b.first,c2 = a.second - b.second;if(c1 < 0) c1 += Mod1;if(c2 < 0) c2 += Mod2;return make_pair(c1,c2);
}hashv operator* (const hashv &a,const hashv &b)
{int c1 = (ll)a.fi * b.fi % Mod1,c2 = (ll) a.se * b.se % Mod2;return make_pair(c1,c2);
}
struct Hash {hashv hs[N],pw[N];inline void prepare() {pw[0] = {1,1};hs[0] = {0,0};for(int i = 1;i < N;i ++) {pw[i] = pw[i - 1] * bas;}}inline void init(int n,char s[]) {for(int i = 1;i <= n;i ++) {hs[i] = hs[i - 1] * bas + make_pair(s[i],s[i]);}}inline hashv query(int l,int r) {if(l > r) return {0,0};return hs[r] - hs[l - 1] * pw[r - l + 1];}
}T[2];
//题意:给定一个字符串串,可以将子串反转,能否成为回文串//思路:hash,回文的比较为:定义反串,比较原串翻转[l,r]后的hash与反串翻转对应的hash
int n,m;char s[N],t[N];hashv strfz(int pos, int l, int r) { //翻转l,r,三部分(1~l-1),(r+1,n)不动,(l,r)为反串 hashv ans = T[pos].query(1, l - 1) * T[pos].pw[n - l + 1];hashv res = T[pos ^ 1].query(n - r + 1, n - r + 1 + r - l) * T[pos].pw[n - r];ans = ans + res + T[pos].query(r + 1, n);//cout<<l<<' '<<r<<' '<<1<<' '<<l-1<<' '<<n - r + 1<<' '<<n - r + 1 + r - l<<' '<<r+1<<' '<<n<<'\n';return ans;
}
void solve()
{cin>>(s+1);int l=1,r=strlen(s+1);n=r;while(l<=r&&s[l]==s[r]) l++,r--;// cout<<l<<' '<<r<<'\n';if(l>=r){ //本身回文cout<<"Yes"<<'\n';return ;}fr(i,1,n){t[i]=s[n-i+1];}T[0].init(n,s); T[1].init(n,t); //定义反串for (int i = l; i <= n; i++) {if (strfz(0, l, i) == strfz(1, n - i + 1, n - i + 1 + i - l)) { //翻转[l,i]//cout<<l<<' '<<i<<'\n'; //比较原串翻转[l,r]后的hash与反串翻转对应的hash//cout<< n - i + 1<<' '<< n - i + 1 + i - l<<'\n';cout << "Yes\n";return;}}for (int i = r; i >= 1; i--) {if (strfz(0, i, r) == strfz(1, n - r + 1, n - r + 1 + r - i)) {cout << "Yes\n";return;}}cout << "No\n";}signed main()
{T[0].prepare();T[1].prepare();ios;int t=1;cin>>t;while(t--) solve();return 0;
}
race\牛客\多校\广西师范大学训练赛\福佑柔泽
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
#include<array>
using namespace std;#define endl '\n'#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define int long long
#define int128 __int128_t
#define ll long long
#define ld long double
typedef unsigned long long ull ;
#define fr(i,l,r) for(int i=l;i<=r;i++)
#define fer(i,x) for(int i=e.head[x];i;i=e.next[i])
#define ufr(i,n,z) for(int i = n;i >= z; i--)
#define pb(x) push_back(x)
#define all(a) a.begin(),a.end()
#define fi first
#define se second
typedef pair<int,int> pr;
const int N = 2e5+10;
const int mod=998244353,inf=1e18;//题意:n个数,选定x使得max(ai^x)最小//思路:01字典树
//01字典树板子
struct Tree_01 {int n, idx;vector<vector<int>> tr;Tree_01(int _n) : n(_n), tr((_n + 1) * 31, vector<int>(2, 0)), idx(0) {}//构造器inline void insert(int x){int p = 0;for(int i=29;i>=0;i--){int nxt = x >> i & 1;if(!tr[p][nxt]) tr[p][nxt] = ++ idx;p = tr[p][nxt];}}/* inline int query(int u, int x, int k) //求出min(ai^x){if (k == -1) return 0;int bit = x >> k & 1;if (tr[u][bit ^ 1]) return query(tr[u][bit ^ 1], x, k - 1) + (1 << k);//先找相等的,求出的为与x异或后最小值else return query(tr[u][bit], x, k - 1);} */inline int query(int p,int f){ //求出最小的max(ai^x)if(f == -1) return 0;if(tr[p][0] && tr[p][1]){ //异或:相同为0,相异为1,最大一定会得到当前数return (1 << f) + min(query(tr[p][0],f - 1),query(tr[p][1],f - 1));} else if(tr[p][0]) return query(tr[p][0],f - 1);else if(tr[p][1]) return query(tr[p][1],f - 1);return 0;}
};
Tree_01 tr(100010);//定义一个字典树
int a[N];
int n,m;void solve()
{cin>>n;fr(i,1,n){cin>>a[i];tr.insert(a[i]);}cout<<tr.query(0,29)<<'\n';
}signed main()
{ios;int t=1;// cin>>t;while(t--) solve();return 0;
}