bzoj 3052 糖果公園

2021-07-04 10:39:28 字數 1473 閱讀 9848

題意:

給出一顆n個結點的樹,每個結點上有一種糖果∈[1,m];

乙個人經過這個結點品嚐糖果j獲得的愉悅度為w[time[j]]*val[j]  (其中time[j]指j的品嚐次數);

給出q次操作,操作有兩種:

1:更改某結點的糖果種類;

2:查詢某兩個結點路徑上的愉悅度總和;

題解:

250s的神題,orz各位神犇;

將樹分塊,每塊n^2/3大小,分成n^1/3塊;

用莫隊演算法統計路徑上每種糖果的數量;

但是這裡有了修改,不能用原來的方式排序了;

所以以左端點所在塊為第一關鍵字,右端點所在塊為第二關鍵字,時間序為第三關鍵字為所有詢問排序;

注意是對詢問排序,而修改仍按時間序儲存;

然後一一處理詢問,每次更改端點之前先把時間調至某次修改之後;

每次調整都是o(1)的,答案就是每個糖果的val乘上w的字首和了;

這樣時間複雜度最壞在o(n^5/3)  (lca的log似乎被忽視了);

我的**可以跑進100s真是榮幸啊233

**:

#include#include#include#include#define n 110000

using namespace std;

typedef long long ll;

struct node

q[n];

int to[n<<1],next[n<<1],head[n];

int st[n],belong[n],deep[n],fa[n][20];

int a[n],s[n];

int opx[n],opf[n],opt[n],last[n];

int cnt,tot,bk,top;

ll v[n],w[n],ans[n];

ll now;

bool vis[n];

bool cmp(node a,node b)

} }st[++top]=x;

}int lca(int x,int y)

return fa[x][0];

}void update(int x,int op)

void change(int t)

} else }

}void slove(int x1,int x2)

while(x2!=g) }

int main()

else

}q=temp;

sort(q+1,q+q+1,cmp);

l=1,r=1,now=0,ti=0;

for(i=1;i<=q;i++)

for(i=1;i<=q;i++)

printf("%lld\n",ans[i]);

return 0;

}

BZOJ 3052 糖果公園

uoj 58 把樹轉化為尤拉序,把詢問對映到尤拉序上,在尤拉序上跑帶修改莫隊。具體的做法可以參考 國家集訓隊2014 集.pdf 的第82頁描述的性質。include include include include include using namespace std const int maxn...

BZOJ3052 糖果公園

0 題目鏈結 1 題目大意 給定一顆n個點的無根樹,每個點有乙個顏色,要進行q次操作,有兩種操作,顏色總數是m。a query操作,給定起始點和終點,對於這條路徑,從起始點出發,對於沿途的點,如果這個點的顏色j是第i次出現,那麼對於這個詢問的答案的貢獻是vi?wj。b change操作,每次修改乙個...

BZOJ 3052 糖果公園 樹上帶修改莫隊

time limit 200 sec memory limit 512 mb submit 1264 solved 637 submit status discuss sample input 84131 2784 submit status discuss home back 這道題我很快的寫完了...