首先考慮給定的a點,那麼b點的位置只可能是a的祖先或者a的不大於k層的兒子
對於祖先,答案很好統計,而對於兒子,就要考慮維護dfs序
對於給定的p,k,兒子部分的答案為整顆子樹中深度不大於dep[p]+k所有sz[v]-1的和
所以很容易想到維護一顆樹套樹或者可持久化線段樹
但是資料範圍有30w,樹套樹肯定會超時,可持久化線段樹常數也很大(即標程)
所以我的做法就在這裡考慮離線處理
我們對所有詢問的dep[p]+k排序,依次加點即可
神奇的是,我的暴力速度在隨機資料下和我的程式差不到一倍,可惜被卡了。。。。。。。。。。。。。
速度比標程快一倍
注意dfs的時候需要手工棧
#include #include #include #include #include #include #include using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define ms(arr,x) memset(arr,x,sizeof(arr))
#define ine(i,u) for(int i=head[u];~i;i=e[i].next)
#define ll long long
inline const int read()
const int n=310010;
int n,q;
struct edgee[n*2];
int head[n],k;
int fa[n],dep[n],sz[n];
int in[n],out[n],dfs_clock;
struct queryqry[n];
ll ans[n];
int dhead[n],pt[n],next[n],kk;
ll sum[n*2];
ll getsum(int l,int r)
void insert(int o,int x)
void add(int d)
bool cmp(query a,query b)
void adde(int u,int v);head[u]=k++;}
void dfs()
if(!f)
s.pop();
} }}void init_d()
}void input()
}void solve()
; ans[i]+=(ll)min(dep[p],k) * (sz[p]-1);
} sort(&qry[1],&qry[q+1],cmp);
int cur=0;
rep(i,1,q)
{ while(cur
濟南學習 Day 3 T2 pm
lyk 快跑!run time limit 5000ms memory limit 64mb 題目描述 lyk 陷進了乙個迷宮!這個迷宮是網格圖形狀的。lyk 一開始在 1,1 位置,出口在 n,m 而且這個迷宮裡有很多怪獸,若第 a 行第 b 列有乙個怪獸,且此時 lyk 處於第 c 行 d 列,...
濟南學習 Day 3 T2 am
看程式寫結果 program time limit 1000ms memory limit 64mb 題目描述 lyk 最近在準備 noip2017 的初賽,它最不擅長的就是看程式寫結果了,因此它拼命地 在練習。這次它拿到這樣的乙個程式 pascal readln n for i 1 to n do...
濟南學習 Day 2 T3 pm
它 問題描述 n個人坐成一圈,其中第k個人拿著乙個球。每次每個人會以一定的概率向 左邊的人和右邊的人傳球。當所有人都拿到過球之後,最後乙個拿到球的人即為 勝者。求第n個人獲勝的概率。所有人按照編號逆時針坐成一圈 輸入格式 第一行乙個數t代表資料組數。對於每組資料,第一行兩個整數n,k如題意所述。接下...