- P3879 [TJOI2010]阅读理解
虽然不需要用trie,但是秉着练习需要,就强行加上trie,没想到其中收获了stl的应用熟练度。首先想的是用set来存取在哪一行,但是可是要求加上结尾不换行,那么在遍历的时候我有很喜欢写for (auto it:se[p])
,显然如果我判断it == se[p].end()
是不正确的,因为it是int。如果判断it==*se[p].end()
好像也不行,于是就写了for循环。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 9;
set<int> se[N];
struct AC {
int tr[N][27], idx = 0;
string str;
void insert(int x) {
int p = 0;
for (int i = 0; str[i]; i ++) {
int id = str[i] - 'a';
if (!tr[p][id])tr[p][id ] = ++ idx;
p = tr[p][id];
}
se[p].insert(x);
}
}T;
int main() {
int n;
cin >> n;
for (int i =1 ; i <= n; i ++) {
int cnt;cin >> cnt;
while (cnt--) {
cin >> T.str;
T.insert(i);
}
}
int m;cin >> m;
for (int i = 1; i <= m; i ++) {
cin >> T.str;
int p = 0;
bool f = 0;
for (int j = 0; T.str[j]; j ++) {
int id = T.str[j] - 'a';
if (id < 0||id >= 26) {f = 1;break;}
if (!T.tr[p][id]) {f = 1;break;}
p = T.tr[p][id];
}
if (f||se[p].size() == 0) {cout << endl;continue;}
auto cmp = se[p].end();
cmp--;
for (auto it = se[p].begin(); it != se[p].end();it++){
if (it == cmp) {
cout << *it <<"
";
} else
cout << *it <<" ";
}
}
}
- HDU6955 Xor sum多校1 .vj
小思维就是求异或和大于等于k的最短区间。然后就是可以转化的是,异或前缀和,然后就可以把异或前缀和放入字典树,然后字典树上节点维护所能到达的最右边的位置,然后查询即可,困难在于实现。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
const ll N = 1e5 + 9;
const ll inf = 0x3f3f3f3f;
struct trie {
ll tr[N *30][2], idx, r[N*30 ];
void init() {
// memset(r, -1, sizeof r);
// memset(tr, 0, sizeof tr);
for (int i = 0; i <= idx; i ++) {
tr[i][0] = tr[i][1] = 0;
r[i] = -1;
}
idx = 0;
}
void insert(ll x, ll pos){
ll p = 0;
bool f = 0;
for (ll i = 32; i >= 0; i--) {
ll id = (x >> i)&1;
if (!tr[p][id])tr[p][id] = ++idx;
p = tr[p][id];
if (id == 1) f = 1;
if (f)
r[p] = pos;
}
}
int ask(ll k,ll sum) {
ll maxr1 = -1, maxr2 =-1;
ll p = 0;
bool f = 0;
for (ll i = 32; i >=0; i --) {
ll id1 = (k >> i) & 1;
ll id2 = (sum >> (i)) & 1;
if (id1 == 1) {
//maxr1 = max(maxr1, r[tr[p][id2 ^ 1]]);
p = tr[p][id2^1];
} else {
maxr2 = max(maxr2, r[tr[p][id2 ^ 1]]);
//maxr1 = max(maxr1, r[tr[p][id2]]);
p = tr[p][id2];
}
if (!p) return max(r[p], maxr2);
}
return max(r[p], maxr2);
}
}T;
ll a[N];
ll sum[N];
void solve() {
int n, k;
T.init();
scanf("%d%d", &n, &k);
ll sum = 0;
ll len = 9999999999999, ansl = 0, ansr = 0;
for (int i = 1; i <=n; i++) {
ll x;scanf("%lld", &x);
sum ^= x;
int pos = T.ask(k , sum);
T.insert(sum, i);
//cout << sum << " ";
if (pos == -1)continue;
if (i - pos + 1 <= 0)continue;
if (len > i - pos+1) {len = i-pos + 1;ansl = pos, ansr = i;}
}
/*----------------------------------------------------------------
3 2 1 3 7 7 4 1 0
*/
if (len <=0||(ansl ==ansr && ansr == 0)) puts("-1");
else printf("%lld %lld
", ansl + 1 , ansr);
}
signed main() {
// freopen("in.txt", "r", stdin);
// freopen("out.out", "w", stdout);
clock_t start_time=clock();
ll t = 1;scanf("%lld", &t);
while (t--) {
solve();
}
clock_t end_time=clock();
//cout<< "Running time is: "<<static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000<<"ms"<<endl;//输出运行时间
}