zoukankan      html  css  js  c++  java
  • 2018.8.8 Noip2018模拟测试赛(二十一)

    日期:

    八月七号

     总分:

    300分

     难度:

    提高 ~ 省选  

     得分:

    112分(OvO)

    题目目录:

      T1:幸福的道路

      T2:Solitaire

      T3:Flags

    赛后心得:

    第一题裸树d啊!竟然花了一个多小时才切掉……

    第二题输出样例成功骗到12分。

    题解:

    T1:幸福的道路

    树形dp,先两次dfs算出每个点的最长路,用两个单调队列维护每天的极差……做完了……

    CODE:

     1 #include<iostream>
     2 #include<queue>
     3 #include<cstdio>
     4 #include<cmath>
     5 using namespace std;
     6 
     7 int n,m,x,tot=0,h[1000005];
     8 long long y,f[1000005],g[1000005],a[1000005];
     9 struct Edge{
    10     int x,next;
    11     long long dis;
    12 }e[2000005];
    13 int q1[1000005],q2[1000005];
    14 
    15 inline void add_edge(int x,int y,long long z){
    16     e[++tot].x=y,e[tot].dis=z;
    17     e[tot].next=h[x],h[x]=tot;
    18 }
    19 
    20 void dfs1(int x,int fa){
    21     for(int i=h[x];i;i=e[i].next){
    22         if(e[i].x==fa)continue;
    23         dfs1(e[i].x,x);
    24         f[x]=max(f[x],f[e[i].x]+e[i].dis);
    25     }
    26 }
    27 
    28 void dfs2(int x,int fa){
    29     long long maxn=0,sec=0;
    30     for(int i=h[x];i;i=e[i].next){
    31         if(e[i].x==fa)continue;
    32         if(f[e[i].x]+e[i].dis>maxn)
    33             sec=maxn,maxn=f[e[i].x]+e[i].dis;
    34         else sec=max(sec,f[e[i].x]+e[i].dis);
    35         g[e[i].x]=g[x]+e[i].dis;
    36     }
    37     for(int i=h[x];i;i=e[i].next){
    38         if(e[i].x==fa)continue;
    39         if(f[e[i].x]+e[i].dis==maxn)
    40             g[e[i].x]=max(g[e[i].x],sec+e[i].dis);
    41         else g[e[i].x]=max(g[e[i].x],maxn+e[i].dis);
    42         dfs2(e[i].x,x);
    43     }
    44 }
    45 
    46 int main(){
    47     scanf("%d%d",&n,&m);
    48     for(int i=2;i<=n;i++){
    49         scanf("%d%lld",&x,&y);
    50         add_edge(i,x,y);
    51         add_edge(x,i,y);
    52     }
    53     dfs1(1,-1),dfs2(1,-1);
    54     for(int i=1;i<=n;i++)a[i]=max(f[i],g[i]);
    55     int l1=1,l2=1,r1=0,r2=0,tmp=0,ans=0;;
    56     for(int i=1;i<=n;i++){
    57         while(l1<=r1&&a[i]<=a[q1[r1]])r1--;
    58         while(l2<=r2&&a[i]>=a[q2[r2]])r2--;
    59         q1[++r1]=i,q2[++r2]=i;
    60         if(a[q2[l2]]-a[q1[l1]]>m){
    61             if(q2[l2]<=q1[l1])tmp=q2[l2],l2++;
    62             else tmp=q1[l1],l1++;
    63         }
    64         ans=max(ans,i-tmp);
    65     }
    66     printf("%d",ans);
    67 }

    T2:Solitaire

     题解戳这里

    CODE:

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4  
     5 #define mod 1000000007
     6 int n,k,ans,f[2005][2005],sum[2005];
     7  
     8 int main(){
     9     scanf("%d%d",&n,&k);
    10     f[0][n+1]=1;
    11     for(int i=1;i<=k;i++)
    12         for(int j=n+1;j>=1;j--){
    13             sum[j]=(sum[j+1]+f[i-1][j])%mod;
    14             f[i][j]=(j<=n-i+1?sum[j]:0);
    15         }
    16     ans=(f[k][1]-f[k-1][1]+mod)%mod;
    17     for(int i=1;i<=n-k-1;i++)ans=(ans+ans)%mod;
    18     printf("%d",ans);
    19 }

    T3:Flags

    2-sat 问题

    题解戳这里

    CODE:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<stack>
      4 #include<algorithm>
      5 #include<cstring>
      6 using namespace std;
      7 
      8 int v[100005];
      9 int n,x,y,tot=0,h[100005];
     10 int scc[100005],dfn[100005],low[100005],C,cnt;
     11 bool vis[100005];
     12 struct Edge{
     13     int x,next;
     14 }e[5000000];
     15 pair<int,int> a[20005];
     16 stack<int> s;
     17 
     18 inline void add_edge(int x,int y){
     19     e[++tot].x=y;
     20     e[tot].next=h[x],h[x]=tot;
     21 }
     22 
     23 void tarjan(int x){
     24     dfn[x]=low[x]=++cnt;
     25     s.push(x),vis[x]=true;
     26     for(int i=h[x];~i;i=e[i].next){
     27         if(!dfn[e[i].x]){
     28             tarjan(e[i].x),low[x]=min(low[x],low[e[i].x]);
     29         }else if(vis[e[i].x]){
     30             low[x]=min(low[x],dfn[e[i].x]);
     31         }   
     32     }
     33     if(dfn[x]==low[x]){
     34         C++;
     35         int tmp;
     36         for(;;){
     37             tmp=s.top();
     38             vis[tmp]=false,scc[tmp]=C;
     39             s.pop();
     40             if(tmp==x)break;
     41         }
     42     }
     43 }
     44 
     45 void build(int o,int l,int r){
     46     if(r-l==1){
     47         add_edge(o+n*2,a[l].second^1);
     48         return;
     49     }
     50     add_edge(o+n*2,(o<<1)+n*2);
     51     add_edge(o+n*2,(o<<1|1)+n*2);
     52     int mid=l+r>>1;
     53     build(o<<1,l,mid),build(o<<1|1,mid,r);
     54 }
     55 
     56 void link(int o,int l,int r,int x,int y,int a){
     57     if(l>=x&&r<=y){
     58         add_edge(a,o+n*2);
     59         return;
     60     }
     61     int mid=l+r>>1;
     62     if(x<mid)link(o<<1,l,mid,x,y,a);
     63     if(y>mid)link(o<<1|1,mid,r,x,y,a);
     64 }
     65 
     66 inline pair<int,int> get(int x,int len){
     67     int l=0,r=x;
     68     pair<int,int> ans;
     69     while(l<r){
     70         int mid=l+r>>1;
     71         if(a[x].first-a[mid].first<len)r=mid;
     72         else l=mid+1;
     73     }
     74     ans.first=l;
     75     l=x,r=n*2-1;
     76     while(l<r){
     77         int mid=l+r+1>>1;
     78         if(a[mid].first-a[x].first<len)l=mid;
     79         else r=mid-1;
     80     }
     81     ans.second=l;
     82     return ans;
     83 }
     84 
     85 inline bool check(int d){
     86     memset(scc,0,sizeof(scc));
     87     memset(dfn,0,sizeof(dfn));
     88     memset(low,0,sizeof(low));
     89     memset(h,-1,sizeof(h)),tot=0;
     90     build(1,0,n*2);
     91     for(int i=0;i<n*2;i++){
     92         int id=a[i].second;
     93         pair<int,int> x=get(i,d);
     94         if(i<x.second)link(1,0,n*2,i+1,x.second+1,id);
     95         if(x.first<i)link(1,0,n*2,x.first,i,id);
     96     }
     97     C=cnt=0;
     98     for(int i=0;i<n*2;i++)if(!dfn[i])tarjan(i);
     99     for(int i=0;i<n*2;i++)
    100         if(scc[a[i].second]==scc[a[i].second^1])return false;
    101     return true;
    102 }
    103 
    104 int main(){
    105     scanf("%d",&n);
    106     for(int i=0;i<n;i++){
    107         scanf("%d%d",&x,&y);
    108         a[2*i+1]=make_pair(x,2*i+1);
    109         a[2*i]=make_pair(y,2*i);
    110     }
    111     sort(a,a+n*2);
    112     int l=0,r=1000000000;
    113     while(l<r){
    114         int mid=l+r+1>>1;
    115         if(check(mid))l=mid;
    116         else r=mid-1;
    117     }
    118     printf("%d",l);
    119 }
  • 相关阅读:
    RESTful Web 服务
    关于 Java API for RESTful Web Services (JAX-RS) 介绍
    IPV6正则表达式
    使用MyBatis-generator 自动生成MyBatis代码
    JSON.stringfy妙用
    浅拷贝与深拷贝
    vue双向绑定原理与实践
    vue路由当中的导航钩子中关于next()方法的理解
    Promise 异步备忘
    封装van-popup为自己的弹窗组件解决v-moel props单向数据流不能修改的问题。
  • 原文地址:https://www.cnblogs.com/ezoiLZH/p/9461555.html
Copyright © 2011-2022 走看看