• CSPS模拟86-87


    模拟86

    T1,烧水,按位统计贡献,利用某种sao操作避免数位dp

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 const int mod=1000000007;
     6 using namespace std;
     7 int n,m;
     8 int dp1[40],sum[40];
     9 int bin[40];
    10 inline void get1(int x)
    11 {
    12     memset(dp1,0,sizeof(dp1));
    13     if(x<0)return;
    14     for(int i=29;~i;--i)
    15     {
    16         dp1[i]=(x>>(i+1))+1;
    17         if(x&bin[i])dp1[i]=1ll*bin[i]*dp1[i]%mod;
    18         else{
    19             dp1[i]=1ll*(x>>(i+1))*bin[i]%mod;
    20             dp1[i]+=(x&(bin[i]-1));++dp1[i];
    21             if(dp1[i]>=mod)dp1[i]-=mod;
    22         }
    23     }
    24 }
    25 int main()
    26 {
    27     for(int i=0;i<=30;++i)bin[i]=1<<i;
    28     int T;scanf("%d",&T);
    29     while(T--)
    30     {
    31         scanf("%d%d",&m,&n);
    32         memset(sum,0,sizeof(sum));
    33         get1(n);
    34         for(int i=0;i<=30;++i)sum[i]+=dp1[i];
    35         get1(m-1);
    36         for(int i=0;i<=30;++i)sum[i]-=dp1[i];
    37         int ans=0;const int num=n-m+1;
    38         for(int i=0;i<=30;++i)
    39         {
    40             ans+=2ll*sum[i]%mod*(num-sum[i])%mod*bin[i]%mod;
    41             if(ans>=mod)ans-=mod;
    42         }
    43         ans=((ans%mod)+mod)%mod;
    44         cout<<ans<<endl;
    45         
    46     }
    47 }
    View Code

    T2,博弈,考场上推出了最小为0时的答案,以为能找出规律,连暴力都没打,kuku

    正解为用必败状态筛必胜状态来保证复杂度。%%%脸哥压表,处理出不合法状态hash掉,最后在数组里lower_bound即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define re register
     6 using namespace std;
     7 int n,m;
     8 int a[5];
     9 char dp[301][301][301];
    10 int main()
    11 {
    12     for(re short i=0;i<=300;++i)
    13     {
    14         for(re short j=0;j<=300;++j)
    15         {
    16             for(re short k=0;k<=300;++k)
    17             {
    18                 if(dp[i][j][k])continue;
    19                 for(re short o=1;o+i<=300;++o)dp[i+o][j][k]=1;
    20                 for(re short o=1;o+j<=300;++o)dp[i][j+o][k]=1;
    21                 for(re short o=1;o+k<=300;++o)dp[i][j][k+o]=1;
    22                 for(re short o=1;o+i<=300&&o+j<=300;++o)dp[i+o][j+o][k]=1;
    23                 for(re short o=1;o+i<=300&&o+k<=300;++o)dp[i+o][j][k+o]=1;
    24                 for(re short o=1;o+k<=300&&o+j<=300;++o)dp[i][j+o][k+o]=1;
    25                 for(re short o=1;o+i<=300&&o+k<=300&&o+j<=300;++o)dp[i+o][j+o][k+o]=1;
    26             }
    27         }
    28     }
    29     int T;scanf("%d",&T);
    30     while(T--)
    31     {
    32         scanf("%d%d%d",&a[1],&a[2],&a[3]);
    33         if(dp[a[1]][a[2]][a[3]])puts("Yes");
    34         else puts("No");
    35     }
    36 }
    View Code

    T3,dp,对前缀和取max优化。考场上想出了第三维表示四个状态(顶峰,底端,上升,下降),然而没想到转移。

    在最外层枚举区间数,对四种状态用4个变量分别维护最优点转移即可。%%%WWB_star,rnb,milk_feng让我认识到自己的错误

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define N 30040
     6 using namespace std;
     7 int n,K,ans;
     8 int a[N],sum[N],dp[205][N][5];
     9 const int inf=0x3f3f3f3f;
    10 int main()
    11 {
    12     memset(dp,-0x3f,sizeof(dp));
    13     scanf("%d%d",&n,&K);
    14     for(int i=1;i<=n;++i)
    15         scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
    16     int mi=0,ma=0,mi2=0,ma2=0;
    17     for(int i=1;i<=n;++i){
    18         dp[1][i][2]=sum[i]-mi;
    19         dp[1][i][1]=ma-sum[i];
    20         dp[1][i][0]=dp[1][i][2];
    21         dp[1][i][3]=dp[1][i][1];
    22         mi=min(mi,sum[i]);ma=max(ma,sum[i]);
    23     }
    24     for(int j=2;j<K;++j){
    25         mi=ma=mi2=ma2=-inf;
    26         for(int i=j-1;i<=n;++i)
    27         {
    28             dp[j][i][2]=max(dp[j][i][2],ma+2*sum[i]);
    29             dp[j][i][1]=max(dp[j][i][1],mi-2*sum[i]);
    30             
    31             dp[j][i][0]=max(dp[j][i][0],mi2);
    32             dp[j][i][3]=max(dp[j][i][3],ma2);
    33             mi=max(mi,dp[j-1][i][2]+sum[i]*2);
    34             mi=max(mi,dp[j-1][i][0]+sum[i]*2);
    35             
    36             ma=max(ma,dp[j-1][i][1]-sum[i]*2);
    37             ma=max(ma,dp[j-1][i][3]-sum[i]*2);
    38             
    39             ma2=max(ma2,dp[j-1][i][1]);
    40             ma2=max(ma2,dp[j-1][i][3]);
    41             
    42             mi2=max(mi2,dp[j-1][i][2]);
    43             mi2=max(mi2,dp[j-1][i][0]);
    44         }
    45     }
    46     mi=ma=mi2=ma2=-inf;
    47     for(int i=K-1;i<=n;++i)
    48     {
    49         dp[K][i][2]=max(dp[K][i][2],ma+sum[i]);
    50         dp[K][i][1]=max(dp[K][i][1],mi-sum[i]);
    51         
    52         dp[K][i][0]=max(dp[K][i][0],mi2);
    53         dp[K][i][3]=max(dp[K][i][3],ma2);
    54         
    55         mi=max(mi,dp[K-1][i][2]+sum[i]);
    56         mi=max(mi,dp[K-1][i][0]+sum[i]);
    57         
    58         ma=max(ma,dp[K-1][i][1]-sum[i]);
    59         ma=max(ma,dp[K-1][i][3]-sum[i]);
    60         
    61         ma2=max(ma2,dp[K-1][i][1]);
    62         ma2=max(ma2,dp[K-1][i][3]);
    63         
    64         mi2=max(mi2,dp[K-1][i][2]);
    65         mi2=max(mi2,dp[K-1][i][0]);
    66         
    67         ans=max(ans,dp[K][i][2]);
    68         ans=max(ans,dp[K][i][1]);
    69     }
    70     printf("%d
    ",ans);
    71 }
    View Code
    300 145 120 50 110 220 122 160 130

    这个故事告诉我们:rp是个好东西(别败光了)

    模拟87,新的开始,勉强苟住位置(抢到Dybala的第八)

    T1,(妹子)maze

    考场上想了半天才想到是二分答案。然后就疯狂码码码,打了个代码测时长,发现极限数据甚至会达到十几秒,然后疯狂卡常

    最后当我手打堆打到一半,发现我的结构体重载运算符重载反了,赶紧改过来,发现还剩1分钟,慌的一比。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<bitset>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #define N 105
     10 using namespace std;
     11 const double eps=1e-5;
     12 const int dx[]={1,-1,0,0};
     13 const int dy[]={0,0,1,-1};
     14 int n,m,sx,sy,tx,ty;
     15 bool vst[N][N];
     16 double dis[N][N],s;
     17 int a[N][N];
     18 struct node{
     19     int x;
     20     int y;
     21     double z;
     22     friend bool operator <(const node &a,const node &b)
     23     {return a.z>b.z;}
     24 };
     25 /*
     26 struct QAQ{
     27     node a[100500];
     28     int tot;
     29     inline int size(){return tot;}
     30     inline void clear(){tot=0;}
     31     inline node top(){return a[1];}
     32     inline void pop()
     33     {
     34         a[1]=a[tot++];int i=1,j;
     35         while(1)
     36         {
     37             j=i<<1;
     38             if(j>tot)return;
     39             if(a[j+1]<a[j])
     40         }
     41     }
     42 
     43 }
     44 */
     45 priority_queue<node>q;
     46 inline void init()
     47 {
     48     for(register int i=1;i<=n;++i)
     49         for(register int j=1;j<=m;++j)
     50             dis[i][j]=1000000.0;
     51 }
     52 inline node mknd(int x,int y,double z)
     53 {
     54     node a;a.x=x,a.y=y,a.z=z;return a;
     55 }
     56 inline void dijk(double val)
     57 {
     58     while(q.size())q.pop();init();
     59     dis[sx][sy]=0.0;
     60     q.push(mknd(sx,sy,0.0));
     61     int xx,yy,x,y;double z;
     62     while(q.size())
     63     {
     64         x=q.top().x;y=q.top().y;z=q.top().z;q.pop();
     65         if(z!=dis[x][y])continue;if(x==tx&&y==ty)return;
     66         for(register int i=3;~i;--i)
     67         {
     68             xx=x+dx[i];yy=y+dy[i];
     69             if(a[xx][yy])continue;
     70             if(dx[i])
     71             {
     72                 if(dis[xx][yy]>z+val)
     73                 {
     74                     dis[xx][yy]=z+val;
     75                     q.push(mknd(xx,yy,dis[xx][yy]));
     76                 }
     77             }
     78             else
     79             {
     80                 if(dis[xx][yy]>z+1.0)
     81                 {
     82                     dis[xx][yy]=z+1.0;
     83                     q.push(mknd(xx,yy,dis[xx][yy]));
     84                 }
     85             }
     86         }
     87     }
     88 }
     89 inline void work()
     90 {
     91     double l=0.0,r=s,mid;
     92     while(r-l>3e-4){
     93         mid=(l+r)*0.5;dijk(mid);
     94         if(dis[tx][ty]-s>0.0)r=mid;
     95         else l=mid;
     96         if(fabs(dis[tx][ty]-s)<5e-4){l=mid;break;}
     97 //        printf("%.10lf %.10lf
    ",l,r);
     98     }
     99     printf("%.3lf
    ",l);
    100 }
    101 int main()
    102 {
    103 //    freopen("da.in","r",stdin);//freopen("my.out","w",stdout);
    104     scanf("%d%d%d%d%d%d",&n,&m,&sx,&sy,&tx,&ty);
    105     for(int i=1;i<=n;++i)
    106         for(int j=1,x;j<=m;++j)
    107             scanf("%d",&x),a[i][j]=x;
    108     
    109     a[sx][sy]=a[tx][ty]=0;
    110     dijk(1.0);if(dis[tx][ty]>100000.0)return 0;
    111     for(int i=1;i<=n;++i)a[i][0]=a[i][m+1]=1;
    112     for(int i=1;i<=m;++i)a[0][i]=a[n+1][i]=1;
    113     scanf("%lf",&s);work();return 0;
    114 }
    115 /*
    116 4 4
    117 1 1 4 4
    118 0 0 1 1
    119 1 0 0 0
    120 0 0 1 0
    121 0 0 0 0
    122 5
    123 */
    View Code

    T2,bird

    线段树稍显然,考虑去除重复贡献,用到了一些差分的思想,在左端点加入区间,右点存左点,dp值单点插入时暂且不加当前贡献,扫到右端点再加,保证不重复

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<bitset>
     6 #include<vector>
     7 #include<queue>
     8 #define N 500050
     9 using namespace std;
    10 int n,m;
    11 vector<int>v[N];
    12 int sum[N],dp[N];
    13 struct node{
    14     int l,r;
    15 }q[100050];
    16 int A,ans;
    17 int ma[N<<2],tag[N<<2];
    18 inline void upd(int g){ma[g]=max(ma[g<<1],ma[g<<1|1]);}
    19 inline void down(int g)
    20 {
    21     tag[g<<1]+=tag[g];
    22     ma[g<<1]+=tag[g];
    23     tag[g<<1|1]+=tag[g];
    24     ma[g<<1|1]+=tag[g];
    25     tag[g]=0;
    26 }
    27 inline void add(int g,int l,int r,int x,int y,int v)
    28 {
    29     if(l>y||r<x)return;
    30     if(l>=x&&r<=y){ma[g]+=v;tag[g]+=v;return;}
    31     if(tag[g])down(g);
    32     const int m=l+r>>1;
    33     add(g<<1,l,m,x,y,v);add(g<<1|1,m+1,r,x,y,v);
    34     upd(g);
    35 }
    36 inline int ask(int g,int l,int r,int x,int y)
    37 {
    38     if(l>y||r<x)return 0;
    39     if(l>=x&&r<=y)return ma[g];
    40     if(tag[g])down(g);
    41     const int m=l+r>>1;
    42     const int a1=ask(g<<1,l,m,x,y),a2=ask(g<<1|1,m+1,r,x,y);
    43     if(a1>a2)return a1;return a2;
    44 }
    45 int main()
    46 {
    47     scanf("%d%d",&n,&m);
    48     for(int i=1,l,r;i<=n;++i)
    49     {
    50         scanf("%d%d",&l,&r);
    51         if(r<0)continue;
    52         if(l<0)l=0;
    53         v[r+1].push_back(l);
    54         if(r>A)A=r;
    55         ++sum[l];
    56     }
    57     ++A;int al=0;
    58     for(int i=0;i<=A;++i)
    59     {
    60         al+=sum[i];
    61         for(int j=0;j<v[i].size();++j)
    62             add(1,0,A,v[i][j],i-1,1),--al;
    63         dp[i]=ask(1,0,A,0,i-m);
    64         ans=max(ans,dp[i]+al);
    65         add(1,0,A,i,i,dp[i]);
    66     }
    67     cout<<ans<<endl;
    68     return 0;
    69 }
    View Code

    T3,%%%脸哥

    话说脸哥是不是把推荐和反对放反了啊?

  • 相关阅读:
    <Ajax> 四. get请求(验证用户名是否存在)
    <Ajax> 三. 前端和后端通过表单数据交互
    <Ajax> 一. PHP基本使用和基本数据类型
    <Ajax> 二. PHP选择语句和循环语句
    <Bootstrap> 学习笔记八. 导航栏和颁
    <Bootstrap> 学习笔记七. 下拉菜单和标签页
    <Bootstrap> 学习笔记六. 栅格系统使用案例
    <Bootstrap> 学习笔记五. 按钮组的使用
    <Bootstrap> 学习笔记三. 浮动的使用
    <Bootstrap> 学习笔记四. 表单组和输入框组的使用
  • 原文地址:https://www.cnblogs.com/loadingkkk/p/11740988.html
Copyright © 2020-2023  润新知