zoukankan      html  css  js  c++  java
  • 2020 省选模拟测试 Round #5 solution (20/02/04)

    【比赛链接】http://59.61.75.5:8018/contest/215

    A. 格

    【题意】

    有一个 $n$ 行 $m$ 列的矩阵,初始所有位置的权值都为 $0$.

    开始时,你在格子 $(x,y)$ 上。

    每天早上,每个格子里的权值都会增加 $1$.

    每天下午,你可以留在当前格子,或瞬移到上下左右相邻格子中的一个。

    每天晚上,你会获得当前格子里的权值,然后清空当前格。

    求第 $k$ 天晚上后,你所获权值的最大值。

    多组询问。

    【数据范围】$Tle 10^5,\, 1le n,mle 10^9,\,1le xle n,\,1le yle m,\,1le kle 10^{18}$。

    【题解】

    考虑 $n,m geq 2$ 的情况。当且仅当 $n,m$ 均为奇数且 $x,y$ 奇偶性相同时无法刚好走完一遍所有格子。在第一天下午先瞬移到相邻一格即可。因此考虑在最后 $n imes m$ 的时间内走完所有格子即可。若 $k< n times m$ 则走 $k$ 格即为答案。

    考虑 $n=1$ 的情况,$k$ 很大时先走到一端,最后 $m$ 步走完即可。$k$ 较小时先往一边走几步,再折返回去。$m=1$ 同理。

    效率 $O(T)$。期望得分:100。

    【代码】

     1 #include<bits/stdc++.h>
     2 inline long long read ( void )
     3 {
     4     long long x=0;char ch;
     5     while ( !isdigit(ch=getchar()) ) ;
     6     for ( x=ch^48; isdigit(ch=getchar()); ) x=(x<<1)+(x<<3)+(ch^48);
     7     return x;
     8 }
     9 inline long long sum ( long long l,long long r ) { return (l+r)%998244353LL*((r-l+1)%998244353LL)%998244353LL*499122177LL%998244353LL; }
    10 signed main()
    11 {
    12     for ( int T=read();T--; )
    13     {
    14         long long n=read(),m=read(),x=read(),y=read(),k=read();
    15         if ( n>1 and m>1 ) printf("%lld
    ",sum(std::max(k-n*m,0LL)+1,k));
    16         else
    17         {
    18             if ( m==1 ) std::swap(n,m),std::swap(x,y);
    19             y=std::min(y,m-y+1);
    20             if ( m-y+1>=k ) printf("%lld
    ",sum(1,k));
    21             else if ( k>=2*m-y-1 ) printf("%lld
    ",sum(k-m+1,k));
    22             else printf("%lld
    ",sum((k+y-m+1)/2,k));
    23         }
    24     }
    25     return 0;
    26 }
    DTOJ4697

    C. 序列

    【题意】

    已知大小为 $n$ 的一个排列。

    给定一个数 $k$,对这个排列的一个长度大于等于 $2$ 的子序列 $s=(s_1 ,dots,s_p)$,对于所有 $i<p$,若 $s_i​​<k<s_{i+1}$ 或 $s_i​​>k>s_{​i+1}$,则得分加 $1$.

    例如,当 $k=2$ 时,子序列 $5134$ 的得分为 $2$.

    对 $kin [1,n]$,求所有给定排列的子序列的得分和.

    【数据范围】$nle 10^5$。

    【题解】

    考虑一对元素 $i,j$ 的贡献。显然对所有 $k(a_i < k < a_j)$ 造成 $2^{i-1} imes 2^{n-j}$ 的贡献(反向同理)。

    考虑每个 $j$ 造成的贡献。显然会由多个 $i$ 造成。

    仔细分析,发现相当于两种操作:

    ① 对于 $k in [a_j+1,n]$,$w_k += 2^{i-1}$

    ② 对于 $k in [1,a_j-1]$,$ans_k+=w_k imes 2^{n-j}$

    直接用分治或线段树维护即可。

    效率 $O(n log n)$。注意内存限制。期望得分:100。

    【代码】

     1 #include<bits/stdc++.h>
     2 inline int read ( void )
     3 {
     4     int x=0;char ch;
     5     while ( !isdigit(ch=getchar()) ) ;
     6     for ( x=ch^48;isdigit(ch=getchar()); ) x=(x<<1)+(x<<3)+(ch^48);
     7     return x;
     8 }
     9 const int mod=1000000007;
    10 const int maxn=100000+10;
    11 int n,Pow[maxn],Ans[maxn],a[maxn],ans[maxn],val[maxn],add[maxn],del[maxn];
    12 std::pair<int,int> Q1[maxn],Q2[maxn];
    13 inline void CDQ ( int l,int r )
    14 {
    15     if ( l==r ) return;
    16     int mid=(l+r)>>1,cnt1=0,cnt2=0;
    17     CDQ(l,mid);CDQ(mid+1,r);
    18     for ( int i=l;i<=mid;i++ ) Q1[++cnt1]=std::make_pair(a[i],i);
    19     for ( int i=mid+1;i<=r;i++ ) Q2[++cnt2]=std::make_pair(a[i],i);
    20     std::sort(Q1+1,Q1+cnt1+1);std::reverse(Q1+1,Q1+cnt1+1);
    21     std::sort(Q2+1,Q2+cnt2+1);std::reverse(Q2+1,Q2+cnt2+1);
    22     for ( int i=1;i<=cnt1;i++ ) add[i]=(add[i-1]+Pow[Q1[i].second-1])%mod;
    23     for ( int i=1;i<=cnt1+1;i++ ) del[i]=0;
    24     for ( int i=1,j=0;i<=cnt2;i++ )
    25     {
    26         while ( j<cnt1 and Q1[j+1].first>Q2[i].first ) j++;
    27         ans[Q2[i].first+1]=(ans[Q2[i].first+1]+1LL*add[j]*Pow[n-Q2[i].second])%mod;
    28         del[j]=(del[j]+mod-Pow[n-Q2[i].second])%mod;
    29     }
    30     for ( int i=cnt1;i;i-- ) del[i]=(del[i]+del[i+1])%mod;
    31     for ( int i=1;i<=cnt1;i++ ) val[Q1[i].first]=(val[Q1[i].first]+del[i])%mod;
    32 }
    33 inline void solve ( void )
    34 {
    35     for ( int i=1;i<=n;i++ ) val[i]=add[i]=del[i]=ans[i]=0;
    36     CDQ(1,n);
    37     for ( int i=1;i<=n;i++ ) ans[a[i]]=(ans[a[i]]+1LL*Pow[i-1]*val[a[i]])%mod;
    38     for ( int i=1;i<=n;i++ ) ans[i]=(ans[i]+ans[i-1])%mod;
    39     for ( int i=1;i<=n;i++ ) Ans[i]=(Ans[i]+ans[i])%mod;
    40 }
    41 signed main()
    42 {
    43 //    freopen("sequence.in","r",stdin);
    44 //    freopen("sequence.out","w",stdout);
    45     n=read();Pow[0]=1;
    46     for ( int i=1;i<=n;i++ ) a[i]=read(),Pow[i]=2LL*Pow[i-1]%mod;
    47     solve();std::reverse(a+1,a+n+1);solve();
    48     for ( int i=1;i<=n;i++ ) printf("%d
    ",Ans[i]);
    49     return 0;
    50 }
    DTOJ4699
  • 相关阅读:
    Linux安装MySQL5.7.25
    Linux配置jdk
    SpringBoot junit 测试
    SpringBoot jasypt 对配置文件项加密
    关于Hibernate级联操作的总结
    GROUP BY 和 ORDER BY一起使用时,要注意的问题!
    web.xml 中的listener、 filter、servlet 加载顺序及其详解
    Hibernate对象的生命周期(补充)
    hibernate--持久对象的生命周期介绍
    开发属于你自己的标签库!
  • 原文地址:https://www.cnblogs.com/RenSheYu/p/12259404.html
Copyright © 2011-2022 走看看