看到這個標題立刻想到:、
「絕地科學家,八倍不屏息啊,八百里外把頭打啊...」
首先我們發現如果只考慮第二個操作,這棵樹就是假的,我們可以直接莫隊解決
如果考慮換根的話...可以把乙個操作換成小於等於9個操作就可以了
當然怎麼換,有一些非常噁心的分類討論
嚶嚶嚶ynoi 題是好題 但是要卡常 首先要fread & fwrite
然後需要wxh的莫隊寫法
然後要算一下分塊大小
sqrt(q_size) -> (n / sqrt(q_size))
40 -> 100
嚶嚶嚶
#include#define ll long longview codeusing
namespace
std;
inline
char
nc()
inline
intread()
char pbuf[100000] , *pp =pbuf;
inline
void push(const
char
ch)inline
void write(long
long
x)const
int maxn = 100010
;int
n,m,rt;
intqx;
inta[maxn],vi[maxn];
intq_size;
int first[maxn],to[maxn << 1],nx[maxn << 1
],cnt;
inline
void add(int u,int
v)inline
void ins(int u,int
v)structq;
q(int _l,int _r,int _id,int _opt)
bool
operator
< (const q &b)const
return l
}}qs[maxn * 45
];int fa[maxn][23
],dep[maxn],ind[maxn],oud[maxn],reh[maxn],dfn;
inline
void dfs(int
x)oud[x] =dfn;
}ll ans[maxn * 5
];ll now;
intcnt_x[maxn],cnt_y[maxn];
inline
int go_anc(int x , int
y)int xpos[10],ypos[10],opt_x[10],opt_y[10
];int
main()
dfs(rt = 1
);
//return 0;
for(int i=1;i<=m;i++)
int y = read(),z;q_size++;
tx = ty = 0
;
if(x == rt) xpos[++tx] = n , opt_x[tx] = 1
;
else
if(ind[rt] < ind[x] || ind[rt] > oud[x]) xpos[++tx] = oud[x] , opt_x[tx] = 1 , xpos[++tx] = ind[x] - 1 , opt_x[tx] = -1
;
else z = go_anc(x , rt) , xpos[++tx] = n , opt_x[tx] = 1 , xpos[++tx] = oud[z] , opt_x[tx] = -1 , xpos[++tx] = ind[z] - 1 , opt_x[tx] = 1
;
if(y == rt) ypos[++ty] = n , opt_y[ty] = 1
;
else
if(ind[rt] < ind[y] || ind[rt] > oud[y]) ypos[++ty] = oud[y] , opt_y[ty] = 1 , ypos[++ty] = ind[y] - 1 , opt_y[ty] = -1
;
else z = go_anc(y , rt) , ypos[++ty] = n , opt_y[ty] = 1 , ypos[++ty] = oud[z] , opt_y[ty] = -1 , ypos[++ty] = ind[z] - 1 , opt_y[ty] = 1
;
for(int j=1;j<=tx;j++)
for(int k=1;k<=ty;k++)
if(xpos[j] &&ypos[k])
qs[++qx] = q(xpos[j] , ypos[k] , q_size , opt_x[j] *opt_y[k]);
}int si = (int)(n /sqrt(qx));
for(int i=1;i<=qx;i++)qs[i].bl = (qs[i].l - 1) /si;
sort(qs + 1,qs + qx + 1
);
int l = 0,r = 0
;
for(int i=1;i<=qx;i++)
while(r < qs[i].r)
while(l > qs[i].l)
while(r > qs[i].r)
ans[qs[i].id] += now *qs[i].opt;
}for(int i=1;i<=q_size;i++)write(ans[i]);
fwrite(pbuf ,
1 , pp -pbuf , stdout);
}
Ynoi2016 這是我自己發明的
link 支援換根和給定兩個點,求子樹中滿足權值相同的方案數 換根操作和遙遠的國度一題類似,直接對應到 rm 序上處理即可 後面的問題和 texttt 類似 仍然使用子樹對應在 rm 序上是一段連續區間,然後容斥得到下式 sum get l 1 1,x times get l 2 1,x get r...
Ynoi2016 這是我自己的發明(莫隊)
話說這道題資料是不是都是鏈啊,我不手動擴棧就全 re 不過 a 了這題還是很爽的,通過昨晚到今天早上的奮鬥,終於肝出了這題 其實樓上說的也差不多了,就是把區間拆掉然後莫隊瞎搞 弱化版 bzoj snoi2017 乙個簡單的詢問 那我先講弱化版吧 可以發現 sum get l 1,r 1,x time...
Ynoi2016 鏡中的昆蟲
區間不用種類的數的個數。這個問題可以轉化為對每個點維護乙個 pre 詢問 l sim r 中,有多少個位置是在 0 sim l 1 之間的。這個問題可以用二維偏序做。然後對於區間賦值的操作,可以證明,如果我們找到所有有變化的位置並且把它改掉,它的總更改次數為 o n m 級別的。那具體實現可以用 s...