data-2020-11-19
阿新 • • 發佈:2020-11-19
今日模擬賽說實話打得不行。
三道題都會做,但是 T3 寫炸了。
大概從 T3 得出了自己的一些問題:
\(1.\) 樹剖已經開始出現打錯的現象了。
\(2.\) 對於那種需要撤銷,刪除的操作,若有特殊情況需要跳出,必須在跳出前先進行此類操作。
今日寫的題:模擬賽的三道(T2 個人覺得沒有問題,SPJ 鍋了也不好檢驗)。
又是算日期,這次我大概掌握做這種題的套路了,找到合適的迴圈節把資料變小然後直接跑暴力就行了。
考慮 DP, \(f_{i,j}\) 表示到第 \(i\) 個位置,前面一共塞了 \(j\) 個人的最小 low 值,然後這類需要輸方案的 Dp 無非就是記錄一下前驅。
寫了一個大常數 \(\log^2\),最後一個點死都卡不過去。
有幾個問題也暴露出來了:
\(1.\) 不少資料結構題我在想到做法之後就基本不會繼續考慮題目本身,而是直接去考慮程式碼實現了,以至於用錯誤複雜度的方法寫半天。
\(2.\) 並查集經常忘記路徑壓縮。(自從 怎樣更有力氣 那道題開始就經常犯這個錯誤)
#include <stdio.h> #include <vector> #include <algorithm> #define LL long long using namespace std; const int N=1e5+3; const int M=3e5+3; int n,m; inline void jh(int &x,int &y){x^=y^=x^=y;return;} inline int max(int x,int y){return x>y?x:y;} inline int min(int x,int y){return x<y?x:y;} struct Rin { char c; inline char gc() { static char rea[M]; static char *head,*tail; return head==tail&&(tail=(head=rea)+fread(rea,1,M,stdin),head==tail)?EOF:*head++; } inline Rin&operator >>(int &x) { x=0; bool bj=false; for(c=gc();c>'9'||c<'0';c=gc())if(c=='-'){c=gc();bj=true;break;} for(;c>='0'&&c<='9';c=gc())x=(x<<1)+(x<<3)+(c^'0'); if(bj)x=-x; return *this; } inline Rin&operator <<(LL x) { static char a[66]; static int tail; if(!x)putchar(48); else { tail=0; if(x<0){x=-x;putchar('-');} for(;x;x/=10)a[++tail]=x%10; for(;tail;tail--)putchar(a[tail]+48); } putchar('\n'); return *this; } }rin; int F[N]; inline int find(int x){return (F[x]==x)?(x):(F[x]=find(F[x]));} struct cow { int y,z; cow(int y_,int z_){y=y_;z=z_;return;} }; vector<cow>to[N]; struct milk { int x,y,z; bool bj; inline void add(){to[x].push_back(cow(y,z));to[y].push_back(cow(x,z));bj=true;return;} }a[M]; int c[M]; int psc; inline bool myru_a(milk x,milk y){return x.z<y.z;} inline bool myru_b(int x,int y){return a[x].z<a[y].z;} struct zjj { int ls,rs; int s; }t[N*25]; int st[N]; int cutt; inline void make_tree(int l,int r,int i) { t[i].ls=t[i].rs=t[i].s=0; if(l==r)return; int mid=(l+r)>>1; make_tree(l,mid,t[i].ls=++cutt); make_tree(mid+1,r,t[i].rs=++cutt); return; } inline void add_tree(int l,int r,int now,int last,int s) { t[now]=t[last];t[now].s++; if(!t[now].ls)return; int mid=(l+r)>>1; if(mid>=s)add_tree(l,mid,t[now].ls=++cutt,t[last].ls,s); else add_tree(mid+1,r,t[now].rs=++cutt,t[last].rs,s); return; } struct prpr { int fa; int dep; int top; }T[N]; int num[N]; int son[N]; int lar[N]; int val[N]; int nam; inline void dfs_down(int now,int fa) { lar[now]=1; int maxl=0; for(int i=to[now].size()-1;i>=0;i--) { int y=to[now][i].y,z=to[now][i].z; if(y==fa)continue; val[y]=z;dfs_down(y,now);lar[now]+=lar[y]; if(lar[y]>maxl)son[now]=y; } return; } inline void add_list(int now){T[nam+1].fa=num[now];T[nam+1].dep=T[num[now]].dep+1;return;} inline void make_list(int now,int fa) { num[now]=++nam; add_tree(1,psc,st[nam]=++cutt,st[nam-1],val[now]); T[nam].top=num[fa]; if(!son[now])return; add_list(now);make_list(son[now],fa); for(int i=to[now].size()-1;i>=0;i--)if(!num[to[now][i].y])add_list(now),make_list(to[now][i].y,to[now][i].y); return; } inline int cheak_rank(int l,int r,int now,int last,int v) { if(t[now].s-t[last].s==0)return 0; if(r<v)return t[now].s-t[last].s; if(l>=v)return 0; int mid=(l+r)>>1; if(mid<v)return t[t[now].ls].s-t[t[last].ls].s+cheak_rank(mid+1,r,t[now].rs,t[last].rs,v); else return cheak_rank(l,mid,t[now].ls,t[last].ls,v); } inline int cheak_num(int l,int r,int now,int last,int s) { if(!t[now].ls)return c[l]; int now_s=t[t[now].ls].s-t[t[last].ls].s; int mid=(l+r)>>1; if(now_s>=s)return cheak_num(l,mid,t[now].ls,t[last].ls,s); else return cheak_num(mid+1,r,t[now].rs,t[last].rs,s-now_s); } inline int cheak_(int l,int r,int v){return cheak_num(1,psc,st[r],st[l-1],cheak_rank(1,psc,st[r],st[l-1],v));} inline int work(int now) { int x=num[a[now].x],y=num[a[now].y]; int sum=-0x3f3f3f3f; for(;T[x].top!=T[y].top;) { if(T[T[x].top].dep<T[T[y].top].dep)jh(x,y); sum=max(sum,cheak_(T[x].top,x,a[now].z)); x=T[T[x].top].fa; } if(T[x].dep<T[y].dep)jh(x,y); if(x!=y)sum=max(sum,cheak_(y+1,x,a[now].z)); return c[a[now].z]-sum; } int main() { int i,j; rin>>n>>m; for(i=1;i<=m;i++){rin>>a[i].x>>a[i].y>>a[i].z;a[i].bj=false;} sort(a+1,a+m+1,myru_a); for(i=1;i<=m;i=j){c[++psc]=a[i].z;for(j=i;j<=m&&a[j].z==c[psc];j++)a[j].z=psc;} LL ans=0; for(i=1;i<=n;i++)F[i]=i; for(i=1;i<=m;i++)if(find(a[i].x)!=find(a[i].y))F[find(a[i].x)]=find(a[i].y),a[i].add(),ans+=c[a[i].z]; make_tree(1,psc,st[0]=++cutt); dfs_down(1,0);T[1].dep=1;make_list(1,1); int mins=0x3f3f3f3f; for(i=m;i>=1;i--)if(!a[i].bj)if(c[a[i].z]-c[a[i].z-1]<mins)mins=min(mins,work(i)); ans+=mins; rin<<ans; return 0; }