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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

codeforces contest 1140(D~G)

發(fā)布時(shí)間:2024/4/11 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 codeforces contest 1140(D~G) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

A~C不想寫(xiě)博客了,就不寫(xiě)了,后面的題還是要推一推的,所以寫(xiě)一下

CF 1140 D

題目大意
給出一個(gè)正多邊形,頂點(diǎn)按順序標(biāo)號(hào)為111~nnn,一個(gè)三角劃分的權(quán)值是每個(gè)三角形三個(gè)頂點(diǎn)的編號(hào)乘積之和
求出一個(gè)三角劃分使得這個(gè)三角劃分的權(quán)值是所有的中最小的
n≤500n\le500n500
題解:
區(qū)間dp即可,挺方便的,復(fù)雜度O(n3)\mathcal O(n^3)O(n3)
但是事實(shí)上,這題是個(gè)結(jié)論題,可以直接O(1)\mathcal O(1)O(1)計(jì)算的
我們來(lái)進(jìn)行一下推導(dǎo)
我們考慮111nnn的邊1-n,假設(shè)其所在的三角劃分是Δ\DeltaΔ 1-x-n
如果x≠n?1x\neq n-1x??=n?1,那么邊x-n一定在另一個(gè)三角劃分Δ\DeltaΔ x-k-n(k>xk>xk>x)中
我們考慮這兩個(gè)三角劃分構(gòu)成的四邊形(此處貼了一幅圖,可以根據(jù)圖來(lái)理解下面的證明
我們把這兩個(gè)三角劃分
Δ\DeltaΔ 1-x-n+Δ\DeltaΔ x-k-n改成Δ\DeltaΔ 1-x-k+Δ\DeltaΔ 1-k-n
我們發(fā)現(xiàn)值會(huì)嚴(yán)格變小,即
1?x?n+x?k?n>1?x?k+1?k?n1*x*n+x*k*n>1*x*k+1*k*n1?x?n+x?k?n>1?x?k+1?k?n
這個(gè)不等式很顯然吧,是由兩個(gè)不等式加在一起的
x?k?n>1?k?nx*k*n>1*k*nx?k?n>1?k?n1?x?n>1?x?k1*x*n>1*x*k1?x?n>1?x?k

這樣不停操作,我們發(fā)現(xiàn)最后xxx就是n?1n-1n?1了,然后又轉(zhuǎn)化成子問(wèn)題(即nnn減小了111),所以最后的答案一定是所有三角劃分都有111這個(gè)頂點(diǎn)
那么答案就是
∏i=2n?1i?(i+1)\prod_{i=2}^{n-1}i*(i+1)i=2n?1?i?(i+1)
直接轉(zhuǎn)化成
∏i=2n?1i2+i\prod_{i=2}^{n-1}i^2+ii=2n?1?i2+i
直接平方和公式和等差數(shù)列求和公式代入即可

#include<bits/stdc++.h> typedef long long ll; #define rg register template <typename T> inline void read(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;} template <typename T> inline void printe(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');} template <typename T> inline void print(const T x){if(x<0)putchar('-'),printe(-x);else printe(x);} template <typename T> inline T min(const T a,const T b){return a<b?a:b;} template <typename T> inline T max(const T a,const T b){return a>b?a:b;} int n; int main() {read(n);print((n-1)*n*(n*2-1)/6+n*(n-1)/2-2);return 0; }

CF 1140 E

題目大意:給定一個(gè)值域?yàn)?span id="ozvdkddzhkzd" class="katex--inline">kkk的序列,有些位置還沒(méi)有填上數(shù),求有多少種填數(shù)方式使得這個(gè)序列不存在非1奇長(zhǎng)度回文子串
n,k≤2?105n,k\le2·10^5n,k2?105
題解: 這里有個(gè)長(zhǎng)度回文子串,這是非常好的性質(zhì),我們發(fā)現(xiàn)如果對(duì)于任何iii均滿足ai≠ai+2a_i\neq a_{i+2}ai???=ai+2?,那么這個(gè)序列就是合法的
那么我們可以把奇數(shù)、偶數(shù)位單獨(dú)拖出來(lái),就變成了子問(wèn)題,有多少種填法使得沒(méi)有相鄰數(shù)相同(這個(gè)可以直接dp做),奇偶串答案相乘即可
復(fù)雜度O(n)\mathcal O(n)O(n)

#include<bits/stdc++.h> typedef long long ll; #define rg register template <typename T> inline void read(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;} template <typename T> inline void printe(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');} template <typename T> inline void print(const T x){if(x<0)putchar('-'),printe(-x);else printe(x);} template <typename T> inline T min(const T a,const T b){return a<b?a:b;} template <typename T> inline T max(const T a,const T b){return a>b?a:b;} const int mod=998244353; int n,k,a[200001],b[200001],ta,tb; ll A[200001],B[200001],C[200001];//A,A//A,B//A,non ll ans=1; int main() {read(n),read(k);for(rg int i=1;i<=n;i++)if(i&1)read(a[++ta]);else read(b[++tb]);A[1]=k-1,B[1]=k-2,C[1]=k-1;A[0]=B[0]=C[0]=1;for(rg int i=2;i<=n;i++){A[i]=B[i-1]*(k-1)%mod;B[i]=(B[i-1]*(k-2)+A[i-1])%mod;C[i]=C[i-1]*(k-1)%mod;}for(rg int i=1;i<=ta;i++)if(a[i]==-1){int j=i;while(j<ta&&a[j+1]==-1)j++;if(i==1&&j==ta)ans=ans*C[ta-1]%mod*k%mod;else if(i==1||j==ta)ans=ans*C[j-i+1]%mod;else if(a[i-1]==a[j+1])ans=ans*A[j-i+1]%mod;else ans=ans*B[j-i+1]%mod;i=j+1;}else if(i!=ta&&a[i+1]!=-1&&a[i]==a[i+1])ans=0;for(rg int i=1;i<=tb;i++)if(b[i]==-1){int j=i;while(j<tb&&b[j+1]==-1)j++;if(i==1&&j==tb)ans=ans*C[tb-1]%mod*k%mod;else if(i==1||j==tb)ans=ans*C[j-i+1]%mod;else if(b[i-1]==b[j+1])ans=ans*A[j-i+1]%mod;else ans=ans*B[j-i+1]%mod;i=j+1;}else if(i!=tb&&b[i+1]!=-1&&b[i]==b[i+1])ans=0;print(ans);return 0; }

CF 1140 F

題目大意:在平面直角坐標(biāo)系中,如果有3個(gè)點(diǎn)能作為一個(gè)矩形(邊平行于坐標(biāo)軸)的三個(gè)頂點(diǎn),那么我們可以把這個(gè)矩形的第四個(gè)點(diǎn)也加入點(diǎn)集,直到不能再加入
設(shè)當(dāng)前點(diǎn)集為SSS,不斷的進(jìn)行操作使得點(diǎn)集變?yōu)?span id="ozvdkddzhkzd" class="katex--inline">TTT
現(xiàn)在給出若干點(diǎn)集SSS求每個(gè)對(duì)應(yīng)的∣T∣|T|T
給出的方式是每次加入一個(gè)點(diǎn)或者刪除一個(gè)點(diǎn)
q≤3?105,1≤xi,yi≤3?105q\le3·10^5,1\le x_i,y_i\le3·10^5q3?1051xi?,yi?3?105
題解:
這題真爽
我們考慮假如只有加點(diǎn)操作
我們對(duì)于所有坐標(biāo)點(diǎn),如果有兩個(gè)點(diǎn)橫坐標(biāo)/縱坐標(biāo)相同,那么我們視為這兩個(gè)點(diǎn)是聯(lián)通的
要求的就是所有聯(lián)通快的不同橫坐標(biāo)數(shù)量乘以不同縱坐標(biāo)數(shù)量的和
我們發(fā)現(xiàn)這個(gè)東西大概要開(kāi)set之類的維護(hù),不是很方便,并且在貢獻(xiàn)答案的時(shí)候會(huì)有一些特判(所有單獨(dú)點(diǎn)的聯(lián)通快顯然都貢獻(xiàn)1,但是如果這個(gè)點(diǎn)根本沒(méi)有,那就貢獻(xiàn)0)
方便起見(jiàn),考慮優(yōu)化
我們拆點(diǎn),把橫坐標(biāo)的位置、縱坐標(biāo)的位置拆開(kāi),這樣每個(gè)點(diǎn)的加入視為連一條邊,這個(gè)時(shí)候維護(hù)不同橫坐標(biāo)數(shù)量、不同縱坐標(biāo)數(shù)量就很方便了,直接加就好了,還不會(huì)有貢獻(xiàn)答案的問(wèn)題(我們發(fā)現(xiàn)這個(gè)時(shí)候單獨(dú)一個(gè)點(diǎn)的貢獻(xiàn)是0,而加入一條連向一個(gè)橫坐標(biāo)和一個(gè)縱坐標(biāo)的邊時(shí)能貢獻(xiàn)1)
考慮如何解決刪點(diǎn)的情況
我們發(fā)現(xiàn)如果一個(gè)點(diǎn)被刪除了,那么他貢獻(xiàn)答案的地方一定是一個(gè)區(qū)間,我們直接用線段樹(shù)維護(hù)區(qū)間即可,那么一次插入會(huì)到O(logq)\mathcal O(logq)O(logq)條線段樹(shù)上
考慮如何處理出每個(gè)葉子節(jié)點(diǎn)的答案,經(jīng)典套路,直接dfs即可,然后用可持久化并查集維護(hù)并查集,由于不能路徑壓縮、只能按秩合并,所以并查集復(fù)雜度是O(logq)\mathcal O(logq)O(logq)
總復(fù)雜度O(qlog2q)\mathcal O(qlog^2q)O(qlog2q)
本題后文有彩蛋,請(qǐng)一定要觀看

#include<bits/stdc++.h> typedef long long ll; #define rg register template <typename T> inline void read(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;} template <typename T> inline void printe(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');} template <typename T> inline void print(const T x){if(x<0)putchar('-'),printe(-x);else printe(x);} template <typename T> inline T min(const T a,const T b){return a<b?a:b;} template <typename T> inline T max(const T a,const T b){return a>b?a:b;} const int MAX=2097152; int q,l[MAX],r[MAX],mid[MAX]; std::vector<std::pair<int,int> >irt[MAX]; std::vector<std::pair<int,int> >::iterator pos; void ini(const int root,const int ll,const int rr) {l[root]=ll,r[root]=rr,mid[root]=(ll+rr)>>1;if(ll==rr)return;ini(root<<1,ll,mid[root]),ini(root<<1|1,mid[root]+1,rr); } void insert(const int root,const int wanl,const int wanr,std::pair<int,int>V) {if(wanl==l[root]&&wanr==r[root]){irt[root].push_back(V);return;}if(wanr<=mid[root])insert(root<<1,wanl,wanr,V);else if(wanl>mid[root])insert(root<<1|1,wanl,wanr,V);else insert(root<<1,wanl,mid[root],V),insert(root<<1|1,mid[root]+1,wanr,V); } struct P {int a,b,t;bool operator <(const P B)const{return a==B.a?b<B.b:a<B.a;} }; std::set<P>Q; std::set<P>::iterator Pos; struct info {int v,a,b;void clear(){v=a=b=0;} }; struct node {node*lson,*rson;info v; }t[12600021],*root[600001],empty,*Null; int usdto[600001],id; node*newnode() {node*R=&t[++usdto[id]];R->lson=R->rson=Null,R->v.clear();return R; } int pl;info val; void INSERT(node*las,node*dq,const int root) {if(l[root]==r[root]){dq->v=val;return;}if(pl<=mid[root])INSERT(las->lson,dq->lson=newnode(),root<<1),dq->rson=las->rson;else INSERT(las->rson,dq->rson=newnode(),root<<1|1),dq->lson=las->lson; } info RES; void SEARCH(node*dq,const int root,const int pl) {if(l[root]==r[root]){if(dq->v.v==0)RES=(info){pl,pl<=300000,pl>300000};else RES=dq->v;return;}if(pl<=mid[root])SEARCH(dq->lson,root<<1,pl);else SEARCH(dq->rson,root<<1|1,pl); } ll ans[600001]; info find(const int x) {SEARCH(root[id],1,x);info u=RES;if(u.v==x)return u;return find(u.v); } void dodo(std::pair<int,int> V) { // printf("dodo %d %d %d\n",ans[id],V.first,V.second);V.second+=300000;info u=find(V.first),v=find(V.second);if(u.v==v.v)id+=2,usdto[id]=usdto[id-2],root[id]=root[id-2],ans[id]=ans[id-2];else{if(u.a+u.b<v.a+v.b)std::swap(u,v);id++,usdto[id]=usdto[id-1];root[id]=newnode();pl=v.v,val=(info){u.v,0,0};INSERT(root[id-1],root[id],1);id++,usdto[id]=usdto[id-1];root[id]=newnode();pl=u.v,val=(info){u.v,u.a+v.a,u.b+v.b};INSERT(root[id-1],root[id],1);ans[id]=ans[id-2];// printf("(%lld %d %d %d %d)\n",ans[id],u.a,u.b,v.a,v.b);ans[id]+=(ll)(u.a+v.a)*(u.b+v.b)-(ll)u.a*u.b-(ll)v.a*v.b;} } void undo() { // puts("undo");id-=2; } void dfs(const int root) {if(l[root]>q)return; // printf(">>%d %d\n",l[root],r[root]);for(pos=irt[root].begin();pos!=irt[root].end();pos++)dodo(*pos);if(l[root]==r[root])print(ans[id]),putchar(' ');else dfs(root<<1),dfs(root<<1|1);for(pos=irt[root].begin();pos!=irt[root].end();pos++)undo(); // printf("<<%d %d\n",l[root],r[root]); } int main() {empty.lson=empty.rson=Null=&empty;root[0]=newnode();read(q);ini(1,1,600000);for(rg int i=1;i<=q;i++){P u;read(u.a),read(u.b);if((Pos=Q.find(u))==Q.end()){u.t=i;Q.insert(u);}else{insert(1,(*Pos).t,i-1,std::make_pair((*Pos).a,(*Pos).b));Q.erase(Pos);}}while(Q.size()){Pos=Q.begin();insert(1,(*Pos).t,q,std::make_pair((*Pos).a,(*Pos).b));Q.erase(Pos);}dfs(1);return 0; }

xswl,我以為可持久化并查集是對(duì)的,其實(shí)是3個(gè)log的,T成大傻逼
上面貼出的是TLE代碼
并查集是其實(shí)是可以O(1)\mathcal O(1)O(1)撤銷的,只能重寫(xiě)

#include<bits/stdc++.h> typedef long long ll; #define rg register template <typename T> inline void read(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;} template <typename T> inline void printe(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');} template <typename T> inline void print(const T x){if(x<0)putchar('-'),printe(-x);else printe(x);} template <typename T> inline T min(const T a,const T b){return a<b?a:b;} template <typename T> inline T max(const T a,const T b){return a>b?a:b;} const int MAX=2097152; int q,l[MAX],r[MAX],mid[MAX]; std::vector<std::pair<int,int> >irt[MAX]; std::vector<std::pair<int,int> >::iterator pos; void ini(const int root,const int ll,const int rr) {l[root]=ll,r[root]=rr,mid[root]=(ll+rr)>>1;if(ll==rr)return;ini(root<<1,ll,mid[root]),ini(root<<1|1,mid[root]+1,rr); } void insert(const int root,const int wanl,const int wanr,std::pair<int,int>V) {if(wanl==l[root]&&wanr==r[root]){irt[root].push_back(V);return;}if(wanr<=mid[root])insert(root<<1,wanl,wanr,V);else if(wanl>mid[root])insert(root<<1|1,wanl,wanr,V);else insert(root<<1,wanl,mid[root],V),insert(root<<1|1,mid[root]+1,wanr,V); } struct P {int a,b,t;bool operator <(const P B)const{return a==B.a?b<B.b:a<B.a;} }; std::set<P>Q; std::set<P>::iterator Pos; ll ans; int bcj[600001],ltot[600001],rtot[600001]; int find(const int x) {if(x==bcj[x])return x;return find(bcj[x]); } int cha[600001],chb[600001],opt; void dodo(std::pair<int,int> V) {V.second+=300000;int u=find(V.first),v=find(V.second);opt++;if(u==v)cha[opt]=0;else{if(ltot[u]+rtot[u]<ltot[v]+rtot[v])std::swap(u,v);bcj[v]=u;ans+=(ll)(ltot[u]+ltot[v])*(rtot[u]+rtot[v])-(ll)ltot[u]*rtot[u]-(ll)ltot[v]*rtot[v];ltot[u]+=ltot[v];rtot[u]+=rtot[v];cha[opt]=u,chb[opt]=v;} } void undo() {if(cha[opt]){int u=cha[opt],v=chb[opt];ltot[u]-=ltot[v];rtot[u]-=rtot[v];ans-=(ll)(ltot[u]+ltot[v])*(rtot[u]+rtot[v])-(ll)ltot[u]*rtot[u]-(ll)ltot[v]*rtot[v];bcj[v]=v;}opt--; } void dfs(const int root) {for(pos=irt[root].begin();pos!=irt[root].end();pos++)dodo(*pos);if(l[root]==r[root])print(ans),putchar(' ');else dfs(root<<1),dfs(root<<1|1);for(pos=irt[root].begin();pos!=irt[root].end();pos++)undo(); } int main() {for(rg int i=1;i<=600000;i++){bcj[i]=i;if(i<=300000)ltot[i]++;else rtot[i]++;}read(q);ini(1,1,q);for(rg int i=1;i<=q;i++){P u;read(u.a),read(u.b);if((Pos=Q.find(u))==Q.end()){u.t=i;Q.insert(u);}else{insert(1,(*Pos).t,i-1,std::make_pair((*Pos).a,(*Pos).b));Q.erase(Pos);}}while(Q.size()){Pos=Q.begin();insert(1,(*Pos).t,q,std::make_pair((*Pos).a,(*Pos).b));Q.erase(Pos);}dfs(1);return 0; }

CF 1140 G

題目大意
給出一棵nnn個(gè)節(jié)點(diǎn)的樹(shù),然后將這棵樹(shù)復(fù)制一遍,并且復(fù)制后與復(fù)制前的點(diǎn)連邊,兩棵樹(shù)內(nèi)部分別有樹(shù)邊
這些所有邊都有邊權(quán)
qqq組詢問(wèn),每次給出兩個(gè)點(diǎn),求兩個(gè)點(diǎn)之間的最短路
n≤3?105,q≤6?105n\le 3·10^5,q\le6·10^5n3?105,q6?105
題解:
看起來(lái)好像是求圖上最短路
但實(shí)際上我們發(fā)現(xiàn),這還是一個(gè)樹(shù)上最短路問(wèn)題
考慮我們是怎么求樹(shù)上最短路的——求lca,然后深度減一下即可
對(duì)于這道題,我們考慮,最短路一定會(huì)經(jīng)過(guò)lca在第一棵樹(shù)上的點(diǎn)或者是lca在第二棵樹(shù)上的點(diǎn),所以我們?nèi)绻芴幚硖幰粋€(gè)倍增數(shù)組fi,j,k,lf_{i,j,k,l}fi,j,k,l?(i,j∈[1,n],k,l∈[0,1]i,j\in[1,n],k,l\in[0,1]i,j[1,n],k,l[0,1])表示編號(hào)為iii的點(diǎn)在第kkk棵樹(shù)上到其的2j2^j2j祖先在第lll棵樹(shù)上的最短路
考慮如何轉(zhuǎn)移,我們發(fā)現(xiàn)只需要求出所有的gig_igi?表示樹(shù)上iii這個(gè)節(jié)點(diǎn)所對(duì)應(yīng)的兩個(gè)節(jié)點(diǎn)之間的最短路長(zhǎng)度即可
我們發(fā)現(xiàn)ggg可以兩遍dfs求得,然后fff也可以求出,最后就只要對(duì)于每個(gè)詢問(wèn)倍增就好了
復(fù)雜度O(nlogn)\mathcal O(nlogn)O(nlogn)

#include<bits/stdc++.h> typedef long long ll; #define rg register template <typename T> inline void read(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;} template <typename T> inline void printe(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');} template <typename T> inline void print(const T x){if(x<0)putchar('-'),printe(-x);else printe(x);} template <typename T> inline T min(const T a,const T b){return a<b?a:b;} template <typename T> inline T max(const T a,const T b){return a>b?a:b;} template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;} const int maxn=300001,maxm=600001; int n,q,dep[maxn]; int head[maxn],nxt[maxm],tow[maxm],tmp;ll vau1[maxm],vau2[maxm]; inline void addb(const int u,const int v,const ll w1,const ll w2) {tmp++;nxt[tmp]=head[u];head[u]=tmp;tow[tmp]=v;vau1[tmp]=w1;vau2[tmp]=w2; } ll g[maxn]; void dfs1(const int u,const int fa) {for(rg int i=head[u];i;i=nxt[i]){const int v=tow[i];if(v==fa)continue;dep[v]=dep[u]+1;dfs1(v,u);g[u]=min(g[u],vau1[i]+vau2[i]+g[v]);} } ll f[maxn][21][2][2];int p[maxn][21]; void dfs2(const int u,const int fa) {for(rg int i=head[u];i;i=nxt[i]){const int v=tow[i];if(v==fa)continue;g[v]=min(g[v],vau1[i]+vau2[i]+g[u]);f[v][0][0][0]=vau1[i];f[v][0][0][1]=g[v]+vau2[i];mind(f[v][0][0][0],f[v][0][0][1]+g[u]);mind(f[v][0][0][1],f[v][0][0][0]+g[u]);f[v][0][1][0]=g[v]+vau1[i];f[v][0][1][1]=vau2[i];mind(f[v][0][1][0],f[v][0][1][1]+g[u]);mind(f[v][0][1][1],f[v][0][1][0]+g[u]);p[v][0]=u;dfs2(v,u);} } ll dpu[2],dpv[2],dp[2]; void C() {std::swap(dpu[0],dpv[0]);std::swap(dpu[1],dpv[1]); } void CP(ll*D) {dp[0]=D[0];dp[1]=D[1]; } ll lca(int u,int v) {if(u&1)u=(u+1)>>1,dpu[0]=0,dpu[1]=g[u];else u=(u+1)>>1,dpu[0]=g[u],dpu[1]=0;if(v&1)v=(v+1)>>1,dpv[0]=0,dpv[1]=g[v];else v=(v+1)>>1,dpv[0]=g[v],dpv[1]=0;if(dep[u]<dep[v])std::swap(u,v),C();const int DEP=dep[u]-dep[v];for(rg int i=0;i<=20;i++)if(DEP&(1<<i)){CP(dpu);dpu[0]=min(dp[0]+f[u][i][0][0],dp[1]+f[u][i][1][0]);dpu[1]=min(dp[0]+f[u][i][0][1],dp[1]+f[u][i][1][1]);u=p[u][i];mind(dpu[0],dpu[1]+g[u]);mind(dpu[1],dpu[0]+g[u]);}if(u==v)return min(dpu[0]+dpv[0],dpu[1]+dpv[1]);for(rg int i=20;i>=0;i--)if(p[u][i]!=p[v][i]){CP(dpu);dpu[0]=min(dp[0]+f[u][i][0][0],dp[1]+f[u][i][1][0]);dpu[1]=min(dp[0]+f[u][i][0][1],dp[1]+f[u][i][1][1]);u=p[u][i];mind(dpu[0],dpu[1]+g[u]);mind(dpu[1],dpu[0]+g[u]);CP(dpv);dpv[0]=min(dp[0]+f[v][i][0][0],dpv[1]+f[v][i][1][0]);dpv[1]=min(dp[0]+f[v][i][0][1],dpv[1]+f[v][i][1][1]);v=p[v][i];mind(dpv[0],dpv[1]+g[v]);mind(dpv[1],dpv[0]+g[v]);}CP(dpu);dpu[0]=min(dp[0]+f[u][0][0][0],dp[1]+f[u][0][1][0]);dpu[1]=min(dp[0]+f[u][0][0][1],dp[1]+f[u][0][1][1]);u=p[u][0];mind(dpu[0],dpu[1]+g[u]);mind(dpu[1],dpu[0]+g[u]);CP(dpv);dpv[0]=min(dp[0]+f[v][0][0][0],dpv[1]+f[v][0][1][0]);dpv[1]=min(dp[0]+f[v][0][0][1],dpv[1]+f[v][0][1][1]);v=p[v][0];mind(dpv[0],dpv[1]+g[v]);mind(dpv[1],dpv[0]+g[v]);return min(dpu[0]+dpv[0],dpu[1]+dpv[1]); } int main() {read(n);for(rg int i=1;i<=n;i++)read(g[i]);for(rg int i=1;i<n;i++){int u,v;ll w1,w2;read(u),read(v),read(w1),read(w2);addb(u,v,w1,w2);addb(v,u,w1,w2);}dfs1(1,0);p[1][0]=1,dfs2(1,0);for(rg int j=1;j<=20;j++)for(rg int i=1;i<=n;i++){const int P=p[i][j-1];p[i][j]=p[P][j-1];const int T=p[i][j];f[i][j][0][0]=min(f[i][j-1][0][0]+f[P][j-1][0][0],f[i][j-1][0][1]+f[P][j-1][1][0]);f[i][j][0][1]=min(f[i][j-1][0][0]+f[P][j-1][0][1],f[i][j-1][0][1]+f[P][j-1][1][1]);mind(f[i][j][0][0],f[i][j][0][1]+g[T]);mind(f[i][j][0][1],f[i][j][0][0]+g[T]);f[i][j][1][0]=min(f[i][j-1][1][0]+f[P][j-1][0][0],f[i][j-1][1][1]+f[P][j-1][1][0]);f[i][j][1][1]=min(f[i][j-1][1][0]+f[P][j-1][0][1],f[i][j-1][1][1]+f[P][j-1][1][1]);mind(f[i][j][1][0],f[i][j][1][1]+g[T]);mind(f[i][j][1][1],f[i][j][1][0]+g[T]);}read(q);while(q--){int u,v;read(u),read(v);print(lca(u,v)),putchar('\n');}return 0; }

總結(jié)

以上是生活随笔為你收集整理的codeforces contest 1140(D~G)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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