日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JZOJ 5699. 【gdoi2018 day1】涛涛接苹果(appletree)

發(fā)布時(shí)間:2025/3/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JZOJ 5699. 【gdoi2018 day1】涛涛接苹果(appletree) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Description


Input

Output

Sample Input

10 5 6
1 2 3 4 5 6 7 8 9 10
9 7
7 10
6 5
7 5
5 8
5 1
2 1
3 2
2 4
2 3 4
2 9 5
1 7 3
4 8 2
5 6 6
2 3
2 5
1 4
3 5
5 1
6 1

Sample Output

0
43
4
27
11
13

Data Constraint

Hint

Solution

題意:

  • 給定一棵以 1 為根的樹,樹上結(jié)點(diǎn)上有一些數(shù)字。

  • 這些數(shù)字每過單位 1 時(shí)間會(huì)走到其所在結(jié)點(diǎn)的父親上,結(jié)點(diǎn) 1 上的數(shù)字會(huì)消失。

  • 有若干詢問,問某一時(shí)間一棵子樹中的數(shù)字和。

思路:

  • 我們考慮一個(gè)數(shù)字會(huì)被一個(gè)詢問統(tǒng)計(jì)到是一種什么情況:

  • 設(shè)這個(gè)數(shù)字在 txtx 時(shí)間出現(xiàn)在結(jié)點(diǎn) xx 上,然后會(huì)被結(jié)點(diǎn) yytyty 時(shí)間統(tǒng)計(jì),

  • 那么就會(huì)滿足不等式:

    dep[x]?dep[y]ty?txdep[x]?dep[y]≥ty?txtxtytx≤ty
    xx 必須在 yy 的子樹內(nèi);

  • 其中 dep[i]dep[i] 表示結(jié)點(diǎn) ii 的深度。

  • 考慮①:我們移項(xiàng),就會(huì)有 dep[x]+txdep[y]+tydep[x]+tx≥dep[y]+ty

  • 顯然左邊只會(huì)和 xx 有關(guān),右邊只會(huì)和 yy 有關(guān);

  • 考慮②:我們考慮使用 dfsdfs 序,

  • 那么②等價(jià)于 dfn[x]dfn[y]dfn[x]≥dfn[y]dfn[x]<dfn[x]+size[x]dfn[x]<dfn[x]+size[x]

  • 其中 dfn[i]dfn[i] 表示 iidfsdfs 序,

  • Size[i]Size[i] 表示以 ii 為子樹的結(jié)點(diǎn)個(gè)數(shù)。

  • 綜上,我們把題目中的第 xx 數(shù)字寫成二維平面上的一個(gè)帶權(quán)點(diǎn),

  • 橫坐標(biāo)為 dep[x]+txdep[x]+tx ,縱坐標(biāo)為 dfn[x]dfn[x],權(quán)值為這個(gè)數(shù)字。

  • 那么詢問就相當(dāng)于是詢問一個(gè)矩形的點(diǎn)權(quán)和。

  • 為了支持平面上單點(diǎn)修改,矩形求和。

  • 我們有兩種方法:

    1 . cdq分治+樹狀數(shù)組

  • 我們把修改和詢問在一起按時(shí)間(題目中的 tt)排序,一共 n+m+qn+m+q 個(gè)東西。

  • 我們從 [1,n+m+q][1,n+m+q] 開始遞歸;

  • 對(duì)于遞歸一個(gè) [l,r][l,r] 的區(qū)間,設(shè) mid=(l+r)/2mid=(l+r)/2

  • 我們只考慮 [l,mid][l,mid] 的修改對(duì) [mid+1,r][mid+1,r] 的詢問的貢獻(xiàn);

  • 這之后,遞歸到 [l,mid][l,mid] , [mid+1,r][mid+1,r] 中繼續(xù)處理。

  • 現(xiàn)在我們就只用考慮 [l,mid][l,mid] 的修改對(duì) [mid+1,r][mid+1,r] 的詢問的貢獻(xiàn);

  • 我們可以簡(jiǎn)單地對(duì) [l,mid][l,mid] 中的修改的橫坐標(biāo)排序,然后把縱坐標(biāo)插入樹狀數(shù)組中,

  • 那么 [mid+1,r][mid+1,r] 中的詢問就能通過查詢樹狀數(shù)組來實(shí)現(xiàn)統(tǒng)計(jì)的過程。

    2 . 二維數(shù)據(jù)結(jié)構(gòu)

  • 這個(gè)就直接做就好了。

  • 只要你會(huì)任何二維的數(shù)據(jù)結(jié)構(gòu)就可以。

  • 推薦學(xué)習(xí):樹狀數(shù)組套線段樹

  • 時(shí)間復(fù)雜度 O(Nlog2N)O(Nlog2N)

Code

#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> using namespace std; const int N=1e5+5; struct data {int ty,t,x,w; }a[N*3]; int tot,num; int first[N],nex[N<<1],en[N<<1]; int dep[N],dfn[N],size[N]; int id[N*3]; long long f[N],ans[N]; inline int read() {int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X; } inline void insert(int x,int y) {nex[++tot]=first[x];first[x]=tot;en[tot]=y; } void dfs(int x,int y) {dfn[x]=++tot;dep[x]=dep[y]+1;size[x]=1;for(int i=first[x];i;i=nex[i])if(en[i]^y){dfs(en[i],x);size[x]+=size[en[i]];} } inline bool cmpt(data x,data y) {return x.t<y.t || x.t==y.t && !x.ty && y.ty; } inline bool cmpx(int x,int y) {return a[x].t>a[y].t; } inline void change(int x,int y) {while(x<N) f[x]=y?f[x]+y:0,x+=x&-x; } inline long long find(int x) {long long sum=0;while(x) sum+=f[x],x-=x&-x;return sum; } void solve(int l,int r) {if(l==r) return;int mid=l+r>>1;int nn=l-1,mm=mid;for(int i=l;i<=mid;i++)if(!a[i].ty) id[++nn]=i;for(int i=mid+1;i<=r;i++)if(a[i].ty) id[++mm]=i;if(nn>=l && mm>mid){sort(id+l,id+1+nn,cmpx);sort(id+mid+1,id+1+mm,cmpx);for(int i=mid+1,j=l;i<=mm;i++){while(j<=nn && a[id[j]].t>=a[id[i]].t){change(dfn[a[id[j]].x],a[id[j]].w);j++;}ans[a[id[i]].w]+=find(dfn[a[id[i]].x]+size[a[id[i]].x]-1)-find(dfn[a[id[i]].x]-1);}for(int i=l;i<=nn;i++) change(dfn[a[id[i]].x],0);}if(nn>=l && nn<mid) solve(l,mid);if(mm>mid && mm<r) solve(mid+1,r); } int main() {freopen("appletree.in","r",stdin);freopen("appletree.out","w",stdout);int n=read(),m=read(),q=read();for(int i=1;i<=n;i++){a[++num].x=i;a[num].t=1;a[num].w=read();}for(int i=1;i<n;i++){int x=read(),y=read();insert(x,y);insert(y,x);}dfs(1,tot=0);for(int i=1;i<=m;i++){a[++num].t=read()+1;a[num].x=read();a[num].w=read();}for(int i=1;i<=q;i++){a[++num].ty=1;a[num].t=read();a[num].x=read();a[num].w=i;}sort(a+1,a+1+num,cmpt);for(int i=1;i<=num;i++) a[i].t+=dep[a[i].x];solve(1,num);for(int i=1;i<=q;i++) printf("%lld\n",ans[i]);return 0; }

總結(jié)

以上是生活随笔為你收集整理的JZOJ 5699. 【gdoi2018 day1】涛涛接苹果(appletree)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。