zoukankan      html  css  js  c++  java
  • CSP-S 模拟测试 45 题解

    由于咕掉的题解太多了,所以只能趁改完不动题的时间,来补补坑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 */
    kill

    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 */
    beauty

    T3 wight:

    考试时看错题,以为只要有一个最小生成树包含那条边即可,但实际上是要所有的最小生成树都要包含那条边。

    我们可以先用kruscal 跑出一个最小生成树,那么他现在树边已经在最小生成树上了,所以我们对树边和非树边进行分类讨论。

    对于非树边,因为只有树边才会被他替换下去,所以我们考虑树边对他的影响,考虑这条非树边两个端点的简单路径,加上这条非树边就会构成一个环,对于一个环,任意去掉一条边他还能够连接起n个点,所以这条非树边只要不是这个环上最大权值就可以,即MST上路径最大权值,树剖维护即可,然后把这条非树边本来的权值更新到线段树里边,后面树边情况要用到。

    对于树边,我们考虑非树边对他的影响,同上,所有能够与他成环的非树边,只要有权值比他小的,就可以把它替换掉,所以每条树边的答案是所有与他成环的非树边的最小值减一,还是树剖维护。

    注意:

    1. 要先更新完所有的非树边再更新树边,因为你不知道那条非树边会对那条树边产生影响。
    2. 各种编号的转化一定要搞清楚。
    3. 关于线段树的操作,建树和询问维护的是树边`最大值,更新和懒标记下传是非树边`最小值。
        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 */
      wight
  • 相关阅读:
    hadoop hbase 完全分布式
    在linux 下安装 solr 的IK中文分词
    Solr的多核配置和分布式
    vi命令
    SilverLigth的Chart不要图例(Legend)的方法
    【转载】Silverlight 应用 WCF RIA Services 在 IIS6 部署问题总结
    上下文菜单点击获取ContextMenu实例方法
    WPF中StringFormat的用法可以参照C#中string.Format的用法
    WPF的转换器中使用Brush应注意问题
    VS2010 SL4解决方案前端发现不了解决方案中WCF服务问题
  • 原文地址:https://www.cnblogs.com/leom10/p/11574900.html
Copyright © 2011-2022 走看看