多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > BZOJ 4012 HNOI2015 開店 動態樹分治+二分

BZOJ 4012 HNOI2015 開店 動態樹分治+二分

來源:程序員人生   發布時間:2015-08-04 08:14:11 閱讀次數:3370次

題目大意:給定1棵樹,每一個點有1個色彩,屢次詢問色彩在[l,r]區間內的所有點與某個點之間的距離之和,強迫在線

沒記錯的話這題我知道的有3種解法來著?
(茴香豆的茴有4種寫法泥萌知道嘛…?

1.線段樹保護虛樹
2.點分治+線段樹
3.分塊

第1種方法我不知道在線怎樣弄= = (我其實不知道怎樣在虛樹上進行點定位
第3種方法貌似內存過不去?
因而果斷點分治+線段樹

寫完發現內存還是炸了= = O(nlog2n)的內存說甚么也過不去啊= =

后來發現既然保護的是和不是最值那還要線段樹干嗎= =
直接開個vector保護前綴和直接2分不就行了= =

時間復雜度O(nlog2n)

#include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 150100 #define B 400 using namespace std; typedef vector<pair<int,long long> > abcd; int n,m,A; int a[M]; long long last_ans; namespace Tree{ struct edge{ int to,f,next; bool ban; }table[M<<1]; int head[M],tot=1; int dpt[M],pos[M],T; int log_2[M<<1],min_dpt[M<<1][18]; void Add(int x,int y,int z) { table[++tot].to=y; table[tot].f=z; table[tot].next=head[x]; head[x]=tot; } void DFS(int x,int from) { int i; min_dpt[pos[x]=++T][0]=dpt[x]; for(i=head[x];i;i=table[i].next) if(table[i].to!=from) { dpt[table[i].to]=dpt[x]+table[i].f; DFS(table[i].to,x); min_dpt[++T][0]=dpt[x]; } } void Build_LCA() { int i,j; for(i=2;i<=T;i++) log_2[i]=log_2[i>>1]+1; for(j=1;j<=log_2[T];j++) for(i=1;i+(1<<j)-1<=T;i++) min_dpt[i][j]=min(min_dpt[i][j-1],min_dpt[i+(1<<j-1)][j-1]); } long long LCA_Depth(int x,int y) { x=pos[x];y=pos[y]; if(x>y) swap(x,y); int l=log_2[y-x+1]; return min(min_dpt[x][l],min_dpt[y-(1<<l)+1][l]); } long long Distance(int x,int y) { return dpt[x]+dpt[y]-2*LCA_Depth(x,y); } } pair<long long,int> operator + (const pair<long long,int> x,const pair<long long,int> y) { return make_pair(x.first+y.first,x.second+y.second); } pair<long long,int> operator - (const pair<long long,int> x,const pair<long long,int> y) { return make_pair(x.first-y.first,x.second-y.second); } /* struct Segtree{ Segtree *ls,*rs; long long sum1; int sum2; //sum1代表子樹中所有點到該點的距離之和 //sum2代表子樹中點的個數 void* operator new(size_t) { static Segtree *mempool,*C; if(C==mempool) mempool=(C=new Segtree[1<<15])+(1<<15); C->ls=C->rs=0x0; C->sum1=C->sum2=0; return C++; } friend void Insert(Segtree *&p,int x,int y,int pos,int val) { int mid=x+y>>1; if(!p) p=new Segtree; p->sum1+=val; p->sum2++; if(x==y) return ; if(pos<=mid) Insert(p->ls,x,mid,pos,val); else Insert(p->rs,mid+1,y,pos,val); } pair<long long,int> Query(Segtree *p,int x,int y,int l,int r) { int mid=x+y>>1; if(!p) return make_pair(0ll,0); if(x==l&&y==r) return make_pair(p->sum1,p->sum2); if(r<=mid) return Query(p->ls,x,mid,l,r); if(l>mid) return Query(p->rs,mid+1,y,l,r); return Query(p->ls,x,mid,l,mid) + Query(p->rs,mid+1,y,mid+1,r); } }; */ namespace Dynamic_TDC{ using namespace Tree; abcd sum1[M],sum2[M]; int fa[M]; int Get_Size(int x,int from) { int i,re=1; for(i=head[x];i;i=table[i].next) if(!table[i].ban&&table[i].to!=from) re+=Get_Size(table[i].to,x); return re; } int Get_Centre_Of_Gravity(int x,int from,int size,int &cg) { int i,re=1,flag=true; for(i=head[x];i;i=table[i].next) if(!table[i].ban&&table[i].to!=from) { int temp=Get_Centre_Of_Gravity(table[i].to,x,size,cg); if(temp<<1>size) flag=false; re+=temp; } if(size-re<<1>size) flag=false; if(flag) cg=x; return re; } void DFS(int x,int from,int dpt,abcd &sum1,abcd &sum2) { int i; sum1.push_back(pair<int,long long>(a[x],dpt)); sum2.push_back(pair<int,long long>(a[x],dpt)); for(i=head[x];i;i=table[i].next) if(!table[i].ban&&table[i].to!=from) DFS(table[i].to,x,dpt+table[i].f,sum1,sum2); } int Tree_Divide_And_Conquer(int x) { abcd::iterator it; int i,j,size=Get_Size(x,0); Get_Centre_Of_Gravity(x,0,size,x); sum1[x].push_back(pair<int,long long>(a[x],0)); for(i=head[x];i;i=table[i].next) if(!table[i].ban) { table[i].ban=table[i^1].ban=true; abcd temp; DFS(table[i].to,0,table[i].f,temp,sum1[x]); int y=Tree_Divide_And_Conquer(table[i].to); sum2[y]=temp;fa[y]=x; sum2[y].push_back(pair<int,long long>(-1,0)); sort(sum2[y].begin(),sum2[y].end()); for(j=1;j<sum2[y].size();j++) sum2[y][j].second+=sum2[y][j-1].second; } sum1[x].push_back(pair<int,long long>(-1,0)); sort(sum1[x].begin(),sum1[x].end()); for(j=1;j<sum1[x].size();j++) sum1[x][j].second+=sum1[x][j-1].second; return x; } pair<long long,int> Query(abcd &a,int l,int r) { if(a.empty()) return pair<long long,int>(0,0); abcd::iterator it1=lower_bound(a.begin(),a.end(),pair<int,long long>(l,0)); abcd::iterator it2=lower_bound(a.begin(),a.end(),pair<int,long long>(r+1,0)); it1--;it2--; return make_pair(it2->second-it1->second,it2-it1); } long long Query(int x,int l,int r) { int i; long long re=Query(sum1[x],l,r).first; for(i=x;fa[i];i=fa[i]) { pair<long long,int> temp=Query(sum1[fa[i]],l,r)-Query(sum2[i],l,r); re+=temp.first+temp.second*Distance(x,fa[i]); } return re; } } int main() { using namespace Tree; using namespace Dynamic_TDC; int i,x,y,z; cin>>n>>m>>A; for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); Add(x,y,z);Add(y,x,z); } DFS(1,0);Build_LCA(); Tree_Divide_And_Conquer(1); for(i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); y=(y+last_ans)%A; z=(z+last_ans)%A; if(y>z) swap(y,z); printf("%lld ",last_ans=Query(x,y,z)); } return 0; }
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 大香一本蕉伊线亚洲网 | a级毛片黄片 | www.黄色毛片 | 在线观看亚洲一区 | 国产精品爱久久久久久久小 | 午夜网站视频 | 日本久久久久一级毛片 | www.日本精品| 亚洲人成免费 | 爱爱小视频免费体验区在线观看 | 最新欧洲大片免费在线看 | 欧美大陆日韩一区二区三区 | 亚洲国产欧美日韩精品一区二区三区 | 国产欧美在线观看视频 | 欧美性受xxxx黑人xyx | 中文字幕在线观看国产 | 视频一区二区三区自拍 | 九一国产精品 | 亚洲精品视频观看 | 日韩精品一区二区三区乱码 | 成人自拍视频网 | 国产成人一区二区三区视频免费蜜 | 一区二区免费视频 | 久久日视频 | 日本特黄特色免费大片 | 成人免费一区二区三区在线观看 | 欧美性猛交xxxx乱大交高清 | 亚洲精品视频在线 | 欧美一级影院 | a成人| 亚洲国产成人久久一区www | 亚洲女人天堂网 | 亚洲一区二区精品推荐 | 亚洲天堂女人 | 国产日韩片| 最近中文免费高清字幕 | 92看片淫黄大片欧美看国产片 | 国产一级淫片a免费播放口欧美 | 亚洲精品色综合久久久 | 狠狠躁天天躁 | 天堂精品 |