codeforces 342E Xenia and Tree

本文提供了一道关于树结构的算法题的解答方案,该题涉及节点染色和查询最短路径的问题,并通过RMQ离线版本实现了O(1)的时间复杂度。

http://www.elijahqi.win/2018/03/04/codeforces-342e-xenia-and-tree/
题目描述

Xenia the programmer has a tree consisting of

n
n nodes. We will consider the tree nodes indexed from 1 to

n
n . We will also consider the first node to be initially painted red, and the other nodes — to be painted blue.

The distance between two tree nodes

v
v and

u
u is the number of edges in the shortest path between

v
v and

u
u .

Xenia needs to learn how to quickly execute queries of two types:

paint a specified blue node in red;
calculate which red node is the closest to the given one and print the shortest distance to the closest red node.
Your task is to write a program which will execute the described queries.

输入输出格式

输入格式:
The first line contains two integers

n
n and

m
m

(2<=n<=10^{5},1<=m<=10^{5})
(2<=n<=105,1<=m<=105) — the number of nodes in the tree and the number of queries. Next

n-1
n−1 lines contain the tree edges, the

i
i -th line contains a pair of integers

a_{i},b_{i}
ai​,bi​

(1<=a_{i},b_{i}<=n,a_{i}≠b_{i})
(1<=ai​,bi​<=n,ai​≠bi​) — an edge of the tree.

Next

m
m lines contain queries. Each query is specified as a pair of integers

t_{i},v_{i}
ti​,vi​

(1<=t_{i}<=2,1<=v_{i}<=n)
(1<=ti​<=2,1<=vi​<=n) . If

t_{i}=1
ti​=1 , then as a reply to the query we need to paint a blue node

v_{i}
vi​ in red. If

t_{i}=2
ti​=2 , then we should reply to the query by printing the shortest distance from some red node to node

v_{i}
vi​ .

It is guaranteed that the given graph is a tree and that all queries are correct.

输出格式:
For each second type query print the reply in a single line.

输入输出样例

输入样例#1: 复制

5 4
1 2
2 3
2 4
4 5
2 1
2 5
1 2
2 5
输出样例#1: 复制

0
3
2
每sqrt(n)个就暴力做一遍 比较最小 如果到达sqrt(n)了 就全局bfs一下将这些信息更新到每个点里面 保证每次询问的都是sqrt(n)的内容 另外这里的lca我选择了rmq的离线版本 o(1)回答询问 否则复杂度可能变成n*sqrt(n)*log(n)

#include<cmath>
#include<queue>
#include<cstdio>
#include<algorithm>
#define inf 0x3f3f3f3f
#define N 110000
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();}
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
    return x*f;
}
int cnt,h[N],n,m,nn,qq[N],top,mn[N<<1][20],dep[N],dis[N],Log[N<<1],pos[N],num;
struct node{
    int y,next;
}data[N<<1];
inline void dfs(int x,int fa){
    mn[++cnt][0]=x;pos[x]=cnt;
    for (int i=h[x];i;i=data[i].next){
        int y=data[i].y;if (y==fa) continue;
        dep[y]=dep[x]+1;dis[y]=dep[y];dfs(y,x);mn[++cnt][0]=x;
    }
}
inline void init(){
    int t=Log[cnt];
    for (int j=1;j<=t;++j)
        for (int i=1;i+(1<<j)-1<=cnt;++i)
            if (dep[mn[i][j-1]]<dep[mn[i+(1<<j-1)][j-1]])
                mn[i][j]=mn[i][j-1];else mn[i][j]=mn[i+(1<<j-1)][j-1];
}
inline int lca(int x,int y){
    x=pos[x];y=pos[y];if (x>y) swap(x,y);int t=Log[y-x+1];
    return dep[mn[x][t]]<dep[mn[y-(1<<t)+1][t]]?mn[x][t]:mn[y-(1<<t)+1][t];
}
inline int calc(int x,int y){return dep[x]+dep[y]-(dep[lca(x,y)]<<1);}
inline void bfs(){
    queue<int>q;for (int i=1;i<=top;++i) q.push(qq[i]),dis[qq[i]]=0;top=0;
    while(!q.empty()){
        int x=q.front();q.pop();
        for (int i=h[x];i;i=data[i].next){
            int y=data[i].y;
            if (dis[x]+1<dis[y]) dis[y]=dis[x]+1,q.push(y);
        }
    }
}
int main(){
//  freopen("cf342e.in","r",stdin);
    n=read();m=read();nn=sqrt(n);Log[0]=-1;
    for (int i=1;i<=n<<1;++i) Log[i]=Log[i>>1]+1;
    for (int i=1;i<n;++i) {
        int x=read(),y=read();
        data[++num].y=y;data[num].next=h[x];h[x]=num;
        data[++num].y=x;data[num].next=h[y];h[y]=num;
    }dfs(1,0);init();cnt=0;
    //for (int i=1;i<=n;++i) printf("%d ",dis[i]);
//  printf("%d ",lca(2,5)); printf("%d ",lca(3,2)); printf("%d \n",lca(8,9));
    while(m--){
        int op=read(),x=read();
        if (op==1) {if (top==nn) bfs();qq[++top]=x;continue;}
        int tmp=inf;for (int i=1;i<=top;++i) tmp=min(tmp,calc(qq[i],x));
        tmp=min(tmp,dis[x]);printf("%d\n",tmp);
    }
    return 0;
}
### Codeforces 887E Problem Solution and Discussion The problem **887E - The Great Game** on Codeforces involves a strategic game between two players who take turns to perform operations under specific rules. To tackle this challenge effectively, understanding both dynamic programming (DP) techniques and bitwise manipulation is crucial. #### Dynamic Programming Approach One effective method to approach this problem utilizes DP with memoization. By defining `dp[i][j]` as the optimal result when starting from state `(i,j)` where `i` represents current position and `j` indicates some status flag related to previous moves: ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = ...; // Define based on constraints int dp[MAXN][2]; // Function to calculate minimum steps using top-down DP int minSteps(int pos, bool prevMoveType) { if (pos >= N) return 0; if (dp[pos][prevMoveType] != -1) return dp[pos][prevMoveType]; int res = INT_MAX; // Try all possible next positions and update 'res' for (...) { /* Logic here */ } dp[pos][prevMoveType] = res; return res; } ``` This code snippet outlines how one might structure a solution involving recursive calls combined with caching results through an array named `dp`. #### Bitwise Operations Insight Another critical aspect lies within efficiently handling large integers via bitwise operators instead of arithmetic ones whenever applicable. This optimization can significantly reduce computation time especially given tight limits often found in competitive coding challenges like those hosted by platforms such as Codeforces[^1]. For detailed discussions about similar problems or more insights into solving strategies specifically tailored towards contest preparation, visiting forums dedicated to algorithmic contests would be beneficial. Websites associated directly with Codeforces offer rich resources including editorials written after each round which provide comprehensive explanations alongside alternative approaches taken by successful contestants during live events. --related questions-- 1. What are common pitfalls encountered while implementing dynamic programming solutions? 2. How does bit manipulation improve performance in algorithms dealing with integer values? 3. Can you recommend any online communities focused on discussing competitive programming tactics? 4. Are there particular patterns that frequently appear across different levels of difficulty within Codeforces contests?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值