由于咕掉的题解太多了,所以只能趁改完不动题的时间,来补补坑qwq,还是太弱了。
考试过程:
到新机房的第一次考试,貌似海星?
第一题一开始就觉得是个贪心,但以为所有小怪兽都要打完,所以想复杂了,但后来发现只要每个人都有怪兽打就吼了,然后显然二分答案,1h 打完。
T2没什么思路,想拆柿子,但没什么用,只qj了链的测试点,用来跑所有测试点竟然得了40pts。
T3一眼看错题,然后一眼wqs二分,然后调到考试结束也没调出样例。
题解:
T1 kill:
先把人和怪兽得坐标sort一下。
显然这n个人打怪兽的最长时间是单调的,然后直接二分答案即可,check时贪心的选择前面的怪兽。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 const int N=5005; 5 int mon[N],per[N]; 6 int maxn; 7 int n,m,s; 8 bool check(int mid){ 9 int res=0,now=1; 10 for(int i=1;i<=n;++i){ 11 while(now<=m&&mid<abs(mon[now]-s)+abs(per[i]-mon[now])) ++now; 12 // res+=abs(mon[now]-s)+abs(per[i]-mon[now]); 13 if(now>m/*n||m*/) return 0;now++; 14 } 15 return 1; 16 } 17 18 signed main(){ 19 scanf("%lld%lld%lld",&n,&m,&s); 20 for(int i=1;i<=n;++i) scanf("%lld",&per[i]); 21 for(int i=1;i<=m;++i) {scanf("%lld",&mon[i]);maxn=max(maxn,mon[i]);} 22 int l=0,r=maxn; 23 sort(per+1,per+n+1); 24 sort(mon+1,mon+m+1); 25 int ans=0; 26 while(l<=r){ 27 // cout<<l<<" "<<r<<endl; 28 int mid=(l+r)>>1; 29 if(check(mid)) r=mid-1,ans=mid; 30 else l=mid+1; 31 } 32 printf("%lld",ans); 33 } 34 /* 35 //jia tanxin 36 #include<bits/stdc++.h> 37 #define int long long 38 using namespace std; 39 const int N=5005; 40 int per[N],mon[N],cost[N]; 41 vector<int > ve[N]; 42 set<int > s[N]; 43 int max(int a,int b){ 44 return a>b?a:b; 45 } 46 47 signed main(){ 48 //freopen("data.in","r",stdin); 49 //freopen("1.out","w",stdout); 50 int n,m,s; 51 scanf("%lld%lld%lld",&n,&m,&s); 52 for(signed i=1;i<=n;++i) scanf("%lld",&per[i]); 53 for(signed i=1;i<=m;++i) scanf("%lld",&mon[i]); 54 for(signed i=1;i<=m;++i){ 55 cost[i]=abs(mon[i]-s); 56 } 57 for(signed i=1;i<=n;++i){ 58 for(signed j=1;j<=m;++j){ 59 ve[i].push_back(cost[j]+abs(per[i]-mon[j])); 60 } 61 } 62 for(signed i=1;i<=n;++i){ 63 sort(ve[i].begin(),ve[i].end()); 64 } 65 int ans=0; 66 for(signed i=1;i<=n;++i){ 67 ans=max(ans,*ve[i].begin()); 68 } 69 printf("%d",ans); 70 } 71 */
T2 beauty:
类似于换根dp的思路,分别考虑子树内和子树外的点对产生的贡献,记$cnt[x]$ 为以$x$为根节点的子树内关键点的个数,那么对于,每个点,考虑所有的关键点在这一个点产生的贡献,子树内有$cnt[x]$个,那么子数外就有$2*k-cnt[x]$个,那么这些点配对的话,经过这一个点,即经过一个单位的距离,产生贡献就是$min(cnt[x],2*k-cnt[x])$,$dfs$一遍即可。
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int N=1e5+10; 5 int d[N],fa[N][22]; 6 int first[N],nex[N<<1],to[N<<1],tot; 7 int ka[N],ver[N],du[N],Root; 8 int mark[N],cnt[N]; 9 int dp[N]; 10 int n,k,QJ,ans; 11 struct Ver{ 12 int dep,id; 13 }p[N]; 14 bool cmp(Ver a,Ver b){ 15 return a.dep<b.dep; 16 } 17 void add(int a,int b){ 18 to[++tot]=b,nex[tot]=first[a],first[a]=tot; 19 } 20 queue<int > q; 21 void bfs(){ 22 d[Root]=1; 23 q.push(Root); 24 while(q.size()){ 25 int x=q.front();q.pop(); 26 for(int i=first[x];i;i=nex[i]){ 27 int y=to[i]; 28 if(d[y]) continue; 29 d[y]=d[x]+1; 30 fa[y][0]=x; 31 for(int j=1;j<=20;++j) fa[y][j]=fa[fa[y][j-1]][j-1]; 32 q.push(y); 33 } 34 } 35 } 36 int Lca(int x,int y){ 37 if(d[x]>d[y]) swap(x,y); 38 for(int i=20;i>=0;--i) if(d[fa[y][i]]>=d[x]) y=fa[y][i]; 39 if(x==y) return x; 40 for(int i=20;i>=0;--i) if(fa[y][i]!=fa[x][i]) y=fa[y][i],x=fa[x][i]; 41 return fa[x][0]; 42 } 43 void pre_dfs(int x,int fa){ 44 if(mark[x]) cnt[x]=1; 45 for(int i=first[x];i;i=nex[i]){ 46 int y=to[i]; 47 if(y==fa) continue; 48 pre_dfs(y,x); 49 cnt[x]+=cnt[y]; 50 } 51 } 52 53 void dfs(int x,int fat){ 54 if(mark[x]) cnt[x]++; 55 for(int i=first[x];i;i=nex[i]){ 56 int y=to[i]; 57 if(y==fat) continue; 58 dfs(y,x); 59 cnt[x]+=cnt[y]; 60 } 61 ans+=min(cnt[x],k*2-cnt[x]); 62 // dp[fa[x][0]]=min(dp[x],k*2-cnt[x]); 63 } 64 65 signed main(){ 66 scanf("%lld%lld%lld",&n,&k,&QJ); 67 const int bz=k<<1; 68 for(int i=1;i<=bz;++i) {scanf("%lld",&ver[i]);mark[ver[i]]=1;} 69 for(int i=1;i<n;++i){ 70 int x,y; 71 scanf("%lld%lld",&x,&y); 72 add(x,y); 73 add(y,x); 74 du[x]++,du[y]++; 75 } 76 if(QJ){ 77 for(int i=1;i<=n;++i){ 78 if(du[i]==1){ 79 Root=i; 80 break; 81 } 82 } 83 bfs(); 84 for(int i=1;i<=bz;++i){ 85 ka[i]=d[ver[i]]; 86 p[i].dep=d[ver[i]]; 87 p[i].id=ver[i]; 88 } 89 sort(p+1,p+k*2+1,cmp); 90 for(int i=1;i<=k;++i){ 91 ans+=abs(p[i].dep+p[bz-i+1].dep-2*d[Lca(p[i].id,p[bz-i+1].id)]); 92 } 93 printf("%lld",ans); 94 } 95 else{ 96 Root=1; 97 memset(dp,0x7f,sizeof(dp)); 98 dfs(1,0); 99 printf("%lld",ans); 100 } 101 } 102 /* 103 7 2 0 104 1 5 6 2 105 1 3 106 3 2 107 4 5 108 3 7 109 4 3 110 4 6 111 */
T3 wight:
考试时看错题,以为只要有一个最小生成树包含那条边即可,但实际上是要所有的最小生成树都要包含那条边。
我们可以先用kruscal 跑出一个最小生成树,那么他现在树边已经在最小生成树上了,所以我们对树边和非树边进行分类讨论。
对于非树边,因为只有树边才会被他替换下去,所以我们考虑树边对他的影响,考虑这条非树边两个端点的简单路径,加上这条非树边就会构成一个环,对于一个环,任意去掉一条边他还能够连接起n个点,所以这条非树边只要不是这个环上最大权值就可以,即MST上路径最大权值,树剖维护即可,然后把这条非树边本来的权值更新到线段树里边,后面树边情况要用到。
对于树边,我们考虑非树边对他的影响,同上,所有能够与他成环的非树边,只要有权值比他小的,就可以把它替换掉,所以每条树边的答案是所有与他成环的非树边的最小值减一,还是树剖维护。
注意:
- 要先更新完所有的非树边再更新树边,因为你不知道那条非树边会对那条树边产生影响。
- 各种编号的转化一定要搞清楚。
- 关于线段树的操作,建树和询问维护的是树边`最大值,更新和懒标记下传是非树边`最小值。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int INF=1e9; 4 const int N=1e6+10; 5 int first_f[N],tot,first[N],tot_c,ans[N]; 6 int n,m; 7 int rcd[N]; 8 struct Edge{ 9 int fr,to,nex,val,id,v; 10 }e[N<<1]; 11 struct EDGE{ 12 int fr,to,nex,val,id; 13 }ee[N<<1]; 14 15 struct SegmentTree{ 16 int l,r,lazy,mx,mi; 17 }tr[N<<2]; 18 int f[N]; 19 int get(int x){ 20 if(f[x]==x) return x; 21 return f[x]=get(f[x]); 22 } 23 24 void add(int x,int y,int z,int k){ 25 e[tot].id=k,e[tot].to=y,e[tot].fr=x; 26 e[tot].nex=first_f[x],e[tot].val=z,first_f[x]=tot++; 27 // e[tot].to=b,e[tot].id=kl,e[tot].fr=a,e[tot].nex=first_f[a],e[tot].val=c,first_f[a]=tot++; 28 } 29 bool cmp(Edge a,Edge b){ 30 return a.val<b.val; 31 } 32 void add_c(int a,int b,int c,int kl){ 33 ee[tot_c].to=b,ee[tot_c].nex=first[a],ee[tot_c].val=c,ee[tot_c].id=kl,first[a]=tot_c++; 34 } 35 36 int fa[N],d[N],size[N],son[N],wt[N]; 37 void dfs1(int x,int fat){//cout<<x<<endl; 38 size[x]=1; 39 for(int i=first[x];i!=-1;i=ee[i].nex){ 40 int y=ee[i].to; 41 if(y==fat) continue; 42 d[y]=d[x]+1;//cout<<x<<" "<<y<<endl; 43 fa[y]=x; 44 wt[ee[i].to]=ee[i].val; 45 rcd[ee[i].to]=ee[i].id; 46 dfs1(y,x); 47 size[x]+=size[y]; 48 if(size[y]>size[son[x]]) son[x]=y; 49 } 50 } 51 int id[N],top[N],cnttt,pos[N]; 52 void dfs2(int x,int topf){//cout<<x<<" "<<topf<<endl; 53 top[x]=topf; 54 id[x]=++cnttt; 55 pos[cnttt]=x; 56 if(son[x]) dfs2(son[x],topf); 57 for(int i=first[x];i!=-1;i=ee[i].nex){ 58 int y=ee[i].to; 59 if(y==fa[x]||y==son[x]) continue; 60 dfs2(y,y); 61 } 62 } 63 void down(int p){ 64 if(tr[p].lazy==INF+1) return ; 65 tr[p<<1].lazy=min(tr[p<<1].lazy,tr[p].lazy); 66 tr[p<<1|1].lazy=min(tr[p<<1|1].lazy,tr[p].lazy); 67 tr[p<<1].mi=min(tr[p].lazy,tr[p<<1].mi); 68 tr[p<<1|1].mi=min(tr[p].lazy,tr[p<<1|1].mi); 69 tr[p].lazy=INF+1; 70 } 71 72 void build(int p,int l,int r){ 73 tr[p].l=l,tr[p].r=r,tr[p].lazy=INF+1; 74 if(l==r){ 75 tr[p].mi=INF+1; 76 tr[p].mx=wt[pos[l]]; 77 return ; 78 } 79 int mid=(l+r)>>1; 80 build(p<<1,l,mid); 81 build(p<<1|1,mid+1,r); 82 tr[p].mx=max(tr[p<<1].mx,tr[p<<1|1].mx); 83 } 84 int q_mx=0; 85 void update(int p,int l,int r,int ll,int rr,int val){//cout<<"U "<<p<<endl; 86 if(ll<=l&&r<=rr){ 87 tr[p].mi=min(tr[p].mi,val); 88 tr[p].lazy=min(tr[p].lazy,val); 89 return ; 90 } 91 down(p); 92 int mid=(tr[p].l+tr[p].r)>>1; 93 if(ll<=mid) update(p<<1,l,mid,ll,rr,val); 94 if(rr>mid) update(p<<1|1,mid+1,r,ll,rr,val); 95 tr[p].mi=min(tr[p<<1].mi,tr[p<<1|1].mi); 96 } 97 void query(int p,int l,int r,int ll,int rr){//cout<<p<<" "<<l<<" "<<r<<" "<<ll<<" "<<rr<<endl; 98 if(ll<=l&&r<=rr){ 99 q_mx=max(q_mx,tr[p].mx); 100 return ; 101 } 102 down(p); 103 int mid=(tr[p].l+tr[p].r)>>1; 104 if(ll<=mid) query(p<<1,l,mid,ll,rr); 105 if(rr>mid) query(p<<1|1,mid+1,r,ll,rr); 106 } 107 void Update(int x,int y,int val){ 108 while(top[x]!=top[y]){//cout<<x<<" "<<y<<endl; 109 if(d[top[x]]<d[top[y]]) swap(x,y); 110 update(1,1,n,id[top[x]],id[x],val); 111 x=fa[top[x]]; 112 } 113 if(d[x]>d[y]) swap(x,y); 114 update(1,1,n,id[x]+1,id[y],val); 115 } 116 int ans_mi=0x7fffffff,ans_mx=0; 117 int Ask(int x,int y){ 118 q_mx=0,ans_mx=0; 119 while(top[x]!=top[y]){//cout<<x<<" "<<y<<endl; 120 if(d[top[x]]<d[top[y]]) swap(x,y); 121 q_mx=0; 122 query(1,1,n,id[top[x]],id[x]); 123 ans_mx=max(ans_mx,q_mx); 124 x=fa[top[x]]; 125 }//cout<<"K"<<endl; 126 if(d[x]>d[y]) swap(x,y); 127 q_mx=0; 128 query(1,1,n,id[x]+1,id[y]); 129 ans_mx=max(ans_mx,q_mx); 130 return ans_mx; 131 } 132 133 void db(int p){ 134 cout<<tr[p].l<<" "<<tr[p].r<<" "<<tr[p].mx<<endl; 135 if(tr[p].l==tr[p].r){ 136 return ; 137 } 138 db(p<<1);db(p<<1|1); 139 } 140 void solve(int p){ 141 if(tr[p].l==tr[p].r){ 142 ans[rcd[pos[tr[p].l]]]=tr[p].mi-1; 143 if(ans[rcd[pos[tr[p].l]]]==INF){ 144 ans[rcd[pos[tr[p].l]]]=-1; 145 } 146 return ; 147 } 148 down(p); 149 solve(p<<1);solve(p<<1|1); 150 } 151 152 int main(){ 153 int Suarez; 154 memset(first,-1,sizeof(first)); 155 scanf("%d%d%d",&n,&m,&Suarez); 156 for(int i=1;i<=n;++i) f[i]=i; 157 for(int i=1;i<=m;++i){ 158 int x,y,z; 159 scanf("%d%d%d",&x,&y,&z); 160 add(x,y,z,i); 161 // add(y,x,z,i); 162 } 163 sort(e+0,e+tot,cmp); 164 int sum=0; 165 for(int i=0;i<tot;i++){ 166 int x=(get(e[i].fr)),y=get(e[i].to); 167 if(x!=y){//cout<<i<<" "; 168 if(get(x)!=get(y)) f[x]=y; 169 sum++; 170 e[i].v=1; 171 add_c(e[i].fr,e[i].to,e[i].val,e[i].id); 172 add_c(e[i].to,e[i].fr,e[i].val,e[i].id); 173 } 174 if(sum==n-1) break; 175 } 176 d[1]=1; 177 dfs1(1,0);//cout<<"Dfs1"<<endl; 178 dfs2(1,1);//cout<<"dfs2"<<endl; 179 build(1,1,n);//cout<<"build"<<endl; 180 // db(1); 181 // for(int i=1;i<=n;++i) cout<<first[i]<<" "; 182 // puts(""); 183 // for(int i=0;i<tot;++i) cout<<e[i].v<<" "; 184 // for(int i=1;i<=n;++i) cout<<top[i]<<" "; 185 // cout<<endl; 186 // for(int i=1;i<=n;++i) cout<<fa[i]<<" "; 187 // for(int i=1;i<=n;++i) cout<<wt[pos[i]]<<" "; 188 // cout<<endl; 189 // cout<<tot<<endl; 190 // for(int i=1;i<=n;++i) cout<<son[i]<<" "; 191 // cout<<endl; 192 for(int i=0;i<tot;i++){ 193 // if(i==19) cout<<"L"<<endl; 194 // if(i==tot-1) cout<<"L"<<endl; 195 // if(i>40) cout<<e[i].v<<" "; 196 if(e[i].v==0){//cout<<i<<endl; 197 ans[e[i].id]=Ask(e[i].fr,e[i].to)-1;//cout<<"ask"<<endl; 198 Update(e[i].fr,e[i].to,e[i].val);//cout<<"upd"<<endl; 199 } 200 } 201 // for(int i=0;i<tot;++i) cout<<e[i].v<<" "; 202 solve(1); 203 for(int i=1;i<=m;++i){ 204 printf("%d ",ans[i]); 205 } 206 } 207 /* 208 4 4 0 209 1 2 1 210 2 3 1 211 3 4 1 212 4 1 2 213 214 out 1 1 1 0 215 216 4 3 0 217 1 2 2 218 2 3 2 219 3 4 2 220 221 out -1 -1 -1 222 223 */