題意:
給出一顆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 這道題我很快的寫完了...