[Codeforces \ # 316 D. Tree Requests] DFS 순서, 오프라인, 이분
8240 단어 ACM____데이터 구조ACM____이분/삼 분
1. 제목 링크
[Codeforces #316 D. Tree Requests]
2. 제목 설명
N 개의 노드 를 지정 한 나 무 는 노드 마다 26 개의 소문 자 중의 한 글자 에 대응 하고 노드 i 의 깊이 는 depi 로 기록 합 니 다.M 번 질문 을 할 때마다 노드 u 의 하위 트 리 (노드 u 포함) 의 모든 깊이 는 depi 의 노드 이 고 각각 해당 하 는 자 모 를 얻어 문자열 을 구성 합 니 다.이 꼬치 를 어떤 배열 에 따라 하나의 회 문 꼬치 를 구성 할 수 있 느 냐 고 물 었 다.
3. 문제 풀이 사고방식
어떤 문자열 의 특정한 배열 은 회 문 열 을 구성 할 수 있 으 며, 이 문자열 의 모든 문 자 는 홀수 번 의 종 수 ≤ 1 로 나타 나 므 로, bitset < 26 > 로 각 문자 의 출현 횟수 의 패 리 티 를 유지 할 수 있 습 니 다.먼저, 나무의 dfs 순 서 를 구 합 니 다. 즉, 각 노드 가 lb 에 들 어가 고 나 오 는 시간 번호 ub 를 구하 고 각 노드 의 깊이 를 구 합 니 다.이렇게 하면 [lb, ub] 으로 이 노드 를 뿌리 노드 로 하 는 서브 트 리 를 표시 할 수 있다.그리고 오프라인 에 대해 물 어보 고 깊이 에 따라 처리 해 주세요.같은 깊이 의 질문.이 깊이 에서 모든 노드 의 접두사 가 다 르 거나 합 쳐 집 니 다.그리고 이 깊이 에서 모든 노드 의 왼쪽 경계 2 점, 오른쪽 경계 에 다시 2 점 을 줍 니 다.그리고 2 점 으로 얻 은 값 이 다 르 거나 이 조회 의 답 을 얻 을 수 있 습 니 다.
4. 구현 코드
#include
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MAXN = 500000 + 5;
const int BITS = 26;
int n, m;
char s[MAXN];
struct Edge {
int v, next;
} edge[MAXN];
int head[MAXN], tot;
struct Node {
int dep, lb, ub, mxdep;
} node[MAXN];
int nid;
vector<int> H[MAXN];
struct Query {
int id, u;
};
vector I[MAXN];
bool Ans[MAXN];
void init() {
tot = 0; nid = 0;
memset(head, -1, sizeof(head));
for(int i = 0; i < MAXN; i++) H[i].clear(), I[i].clear();
}
void add_edge(int u, int v) {
edge[tot] = Edge{v, head[u]};
head[u] = tot ++;
}
void dfs(int u, int k) {
node[u].mxdep = node[u].dep = k;
node[u].lb = ++ nid;
H[k].push_back(u);
for(int i = head[u], v; ~i; i = edge[i].next) {
v = edge[i].v;
dfs(v, k + 1);
node[u].mxdep = max(node[u].mxdep, node[v].mxdep);
}
node[u].ub = nid;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d %d", &n, &m);
init();
for(int u, v = 2; v <= n; v++) {
scanf("%d", &u);
add_edge(u, v);
}
scanf("%s", s + 1);
dfs(1, 1);
for(int i = 0, u, h; i < m; i++) {
scanf("%d %d", &u, &h);
I[h].push_back(Query{i, u});
}
vector<int> L(MAXN), R(MAXN);
vector<bitset > pre(MAXN);
for(int h = 0; h < MAXN; h++) {
int sz = I[h].size(), hsz = H[h].size();
if(sz == 0) continue;
pre[0].reset();
for(int i = 0; i < hsz; i++) {
int& u = H[h][i];
L[i] = node[u].lb;
R[i] = node[u].ub;
pre[i + 1] = pre[i];
pre[i + 1].flip(s[u] - 'a');
}
for(int i = 0; i < sz; i++) {
int& id = I[h][i].id, &u = I[h][i].u;
if(hsz == 0) Ans[id] = true;
else if(node[u].dep >= h) Ans[id] = true;
else if(node[u].mxdep < h) Ans[id] = true;
else {
int &lb = node[u].lb, &ub = node[u].ub;
int LB = lower_bound(L.begin(), L.begin() + hsz, lb) - L.begin();
int UB = upper_bound(R.begin(), R.begin() + hsz, ub) - R.begin() - 1;
if(LB > UB) {
Ans[id] = true;
continue;
}
bitset bs = pre[UB + 1] ^ pre[LB];
if(bs.count() <= 1) Ans[id] = true;
else Ans[id] = false;
}
}
}
for(int i = 0; i < m; i++) {
puts(Ans[i] ? "Yes" : "No");
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Codeforces \ # 316 D. Tree Requests] DFS 순서, 오프라인, 이분N 개의 노드 를 지정 한 나 무 는 노드 마다 26 개의 소문 자 중의 한 글자 에 대응 하고 노드 i 의 깊이 는 depi 로 기록 합 니 다.M 번 질문 을 할 때마다 노드 u 의 하위 트 리 (노드 u 포함)...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.