这样就可以完美的通过了,(最不习惯写离线的算法了
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; int head[600000], ne[600000], v[600000]; int first[600000], nx[600000]; int le[600000], ri[600000], ll; char str[600000]; int tot; int ans[600000]; struct node{ int num, dep, id; bool operator < (const node& rhs) const{ return dep < rhs.dep; } }; node a[600000]; struct segment_tree{ int q[2500000]; int x, y; inline void add(int l, int r, int o){ if(l == r && l == x){ q[o] = y; return; } int mid = (l + r) / 2; if(x <= mid) add(l, mid, 2 * o); if(x > mid) add(mid + 1, r, 2 * o + 1); q[o] = q[2 * o] ^ q[2 * o + 1]; return; } inline int query(int l, int r, int o){ if(x <= l && r <= y){ return q[o]; } int mid = (l + r) / 2; int ret = 0; if(x <= mid) ret ^= query(l, mid, 2 * o); if(y > mid) ret ^= query(mid + 1, r, 2 * o + 1); return ret; } } wt; inline void dfs(int x, int h){ nx[x] = first[h]; first[h] = x; le[x] = ++ ll; for(int i = head[x]; i != -1; i = ne[i]){ dfs(v[i], h + 1); } ri[x] = ll; return; } int main(){ memset(head, -1, sizeof(head)); memset(first, -1, sizeof(first)); int n, m; scanf("%d%d", &n, &m); for(int i = 2; i <= n; i ++){ scanf("%d", &v[i]); ne[i] = head[v[i]]; head[v[i]] = i; v[i] = i; } dfs(1, 1); scanf("%s", str); for(int i = 1; i <= m; i ++){ scanf("%d%d", &a[i].num, &a[i].dep); a[i].id = i; } sort(a + 1, a + m + 1); int i = 1; for( ; i <= m; ){ int height = a[i].dep; for(int j = first[height]; j != -1; j = nx[j]){ wt.x = le[j]; wt.y = (1 << (str[j - 1] - 'a')); wt.add(1, n, 1); } for( ; i <= m && a[i].dep == height; i ++){ wt.x = le[a[i].num]; wt.y = ri[a[i].num]; int hh = wt.query(1, n, 1); int cnt = 0; for(int k = 0; k <= 25; k ++) if(((1 << k) & hh)){ cnt ++; } if(cnt > 1) ans[a[i].id] = 0; else ans[a[i].id] = 1; } for(int j = first[height]; j != -1; j = nx[j]){ wt.x = le[j]; wt.y = 0; wt.add(1, n, 1); } } for(int j = 1; j <= m; j ++){ if(ans[j] == 1) printf("Yes\n"); else printf("No\n"); } return 0; }