對於每個詢問輸出一行乙個整數, 表示答案.
5 5 0
5 5 2 5 5
5 1
2 5
4 2
3 5
1 2 2 3
2 5 1
1 1 1 5
2 3 2
1 3 1 5
0 3
15 5 1
4 1 1 5 4
5 1
3 5
2 3
4 3
2 5 4
2 2 2
1 3 1 5
2 1 2
1 1 2 73 1
這題雖說是資料結構題,但是不很經典
比較經典的做法就是按照dfs序線段樹或者樹鏈剖分,這是比較好想的
但是這題如果這麼想就容易想歪
首先對於每個顏色,開個set記錄這個顏色的點的dfs序,也就是排好序了的
對乙個顏色,每個點自己位置+1,set中dfs序相鄰位置的lca-1,這樣統計貢獻時,直接子樹權值和就行(畫張圖理解一下)
多個顏色就開樹狀陣列套線段樹就行了
#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define n 101000
#define lowbit(x) (x&(-x))
using namespace std;
int a[n],last[n],next[n*2],to[n*2],n,q,zx,f[n][17],bz[n],tot=0,t[n*2],ans,dfn[n],low[n],deep[n],fdfn[n];
struct nodeg[n*200];
set c[n];
typedef set :: iterator it;
void putin(int
x,int
y)void dg(int
x) low[x]=tot;
}int lca(int
x,int
y)void change(int v,int i,int j,int
x,int
y) int
m=(i+j)/2;
if(x
<=m) g[v].l=g[v].l==0?++tot:g[v].l,change(g[v].l,i,m,x,y);
else g[v].r=g[v].r==0?++tot:g[v].r,change(g[v].r,m+1,j,x,y);
g[v].sz=g[g[v].l].sz+g[g[v].r].sz;
}int find(int v,int i,int j,int
x,int
y)void ins(int
x,int
y,int z)
int get(int
x,int l,int r)
int main()
tot=0;deep[1]=1;dg(1);
fo(j,1,16) fo(i,1,n) f[i][j]=f[f[i][j-1]][j-1];
fo(i,1,n) t[i]=i,c[a[i]].insert(dfn[i]),c[i].insert(0),c[i].insert(n+1);
tot=n;
fo(i,1,n)
}while(q--)
if(tag==2)
}}
5507 清華冬令營2018模擬 取石子
直接說做法了,挺好理解的。欽定a b a le b a b。設r x mod a b r x mod a b r xmod a b 分四種情況討論 r 0,a 1 r in 0,a 1 r 0,a 1 這個情況沒有意義。r a,b 1 r in a,b 1 r a,b 1 這個情況下,a aa能多走...
清華2019冬令營模擬12 8 視野
計算幾何弱渣果然就是一點感覺也沒有。首先考慮不刪怎麼做?肯定要把點給離散,那麼現在對於每一小段,要求出是哪條線段最近?按乙個順序掃過去,每一條線段打乙個加入和刪除的標記。由於線段互不相交,所以線段順序不會隨著小段的移動而改變。因此,我們可以用乙個set去維護插入刪除,比較遠近時,就求交,判斷誰近。那...
位元組跳動冬令營2018
給定一棵有根樹,邊有邊權,兩個人輪流操作,每次可以把一條邊的權值減少一,權值變為 0 表示把子樹砍掉,問先手第一輪操作哪些邊使得自己必勝。n 1 06 n leq 10 6 n 10 6之前的部落格,發現這道題本質上是圖的刪邊遊戲。把環縮掉,就變成了樹上刪邊遊戲了。結論是 葉子的 sg 為 0,非葉...