zoukankan      html  css  js  c++  java
  • 模拟测试52,53反思

    这两次考试都挂了不少分,也学到了很多东西。

    52 T1 常数写大正解T成暴力

       T2 数组越界70->50又由于我的智障操作最后一秒50->20

    53 T2 逆推打成正推100->21

       T3 暴力56pts,错解57pts,机智的我交了暴力,还把数组开小了57->43。

    1.虽然不同算法的理论复杂度是一样的,但是常数真的很重要!map常数很大!

    2.在不确定自己打的是对的时候,不要在最后时刻交代码。

    3.期望逆着推,其实不是期望,对于最优决策来说,要么枚举所有决策,

      判断优劣,要么先逆着算出所有的情况的答案,寻找决策(记忆化搜索)

    4.在代码过不了对拍的时候,一定要认真对待暴力。

    5.矩阵快速幂某种程度上是说:x[i][j]表示j转移到i的系数。

    6.记得测一下极限数据。

    T1 平均数

    sb题(谁正解T成暴力谁sb)

     1 #include<cstdio>
     2 #define N 100005
     3 using namespace std;
     4 int a[N],n,k;
     5 long long sum[N],ans;
     6 double tmp[N],q[N];
     7 inline int read()
     8 {
     9     int x=0;char c=getchar();
    10     while(c<'0'||c>'9')c=getchar();
    11     while(c>='0'&&c<='9')x=x*10+c-48,c=getchar();
    12     return x;
    13 }
    14 void solve(int l,int r)
    15 {
    16     if(l==r)return ;
    17     int mid=l+r>>1;
    18     solve(l,mid),solve(mid+1,r);
    19     int pl=l,pr=mid+1,tot=l-1;
    20     while(pl<=mid&&pr<=r)
    21     {
    22         if(tmp[pr]<=tmp[pl]) ans+=(mid-pl+1),q[++tot]=tmp[pr++];
    23         else q[++tot]=tmp[pl++];
    24     }
    25     while(pl<=mid) q[++tot]=tmp[pl],pl++;
    26     while(pr<=r) q[++tot]=tmp[pr],pr++;
    27     for(register int i=l;i<=r;i++) tmp[i]=q[i];
    28     return ;
    29 }
    30 inline bool check(double x)
    31 {
    32     tmp[1]=0;ans=0;
    33     for(register int i=1;i<=n;++i)
    34         tmp[i+1]=sum[i]-i*x;
    35     solve(1,n+1);
    36     return ans<k;
    37 }
    38 inline double _min(double a,double b){return a<b?a:b;}
    39 inline double _max(double a,double b){return a>b?a:b;}
    40 int main()
    41 {
    42     double l=0x7f7f7f7f,r=0;
    43     n=read(),k=read();
    44     for(register int i=1;i<=n;++i)a[i]=read(),l=_min(l,1.0*a[i]),r=_max(r,1.0*a[i]),sum[i]=sum[i-1]+a[i];
    45     while(r-l>1e-5)
    46     {
    47         double mid=(l+r)/2;//printf("%lf",mid);
    48         if(check(mid))l=mid;
    49         else r=mid;
    50     }
    51     printf("%.4lf
    ",l);
    52     return 0;
    53 }
    View Code

    T2 涂色游戏

    我打的很麻烦。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define int long long
     4 using namespace std;
     5 const int mod=998244353;
     6 int C[105][105],dp[105],g[105][105],fx[105][105][105],ed[105],n,m,p,q;
     7 struct M{
     8     int x[105][105];
     9     friend M operator * (const M a,const M b)
    10     {
    11         M c; memset(c.x,0,sizeof c.x);
    12         for(int i=1;i<=p;i++)
    13             for(int j=1;j<=p;j++)
    14                 for(int k=1;k<=p;k++)
    15                     (c.x[i][j]+=a.x[i][k]*b.x[k][j]%mod)%=mod;
    16         return c;
    17     }
    18     void clear()
    19     {
    20         for(int i=1;i<=p;i++)x[i][i]=1;
    21     }
    22     void out(){for(int i=1;i<=p;i++,puts(""))for(int j=1;j<=p;j++)cout<<x[i][j]<<' ';}
    23 }ans,now;
    24 inline void qpower(int b)
    25 {
    26     ans.clear();//ans.out();
    27     for(;b;b>>=1,now=now*now) if(b&1)ans=ans*now;
    28     return ;
    29 }
    30 signed main()
    31 {
    32     scanf("%lld%lld%lld%lld",&n,&m,&p,&q); C[1][0]=C[1][1]=C[0][0]=g[1][1]=1;
    33     for(int i=2;i<=100;C[i++][0]=1)
    34         for(int j=1;j<=i;j++)
    35             C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod,
    36             g[j][i]=(g[j-1][i-1]*j%mod+g[j][i-1]*j%mod)%mod;
    37     for(int i=0;i<=p;i++)
    38         for(int j=0;j<=p;j++)
    39             for(int k=0;k<=j;k++)
    40                 fx[i][j][k]=(fx[i][j][k-1]+C[i][k]*C[p-i][j-k]%mod)%mod;
    41     for(int i=1;i<=p;i++)dp[i]=C[p][i]*g[i][n]%mod;
    42     for(int j=1;j<=p;j++)
    43         for(int k=q-j;k<=p;k++)
    44         {
    45             if(k<1) continue;
    46             if(k<q)now.x[j][k]=(C[p][j]-fx[p-k][j][q-k-1]+mod)%mod*g[j][n]%mod;
    47             else now.x[j][k]=C[p][j]*g[j][n]%mod;
    48         }
    49     qpower(m-1);
    50     for(int i=1;i<=p;i++)
    51         for(int j=1;j<=p;j++)
    52             (ed[i]+=ans.x[i][j]*dp[j]%mod)%=mod;
    53     int ans=0;
    54     for(int j=1;j<=p;j++) (ans+=ed[j])%=mod;
    55     printf("%lld
    ",ans);
    56 }
    View Code

    T3 序列

    开一棵主席树维护询问区间,把每个区间拆成两个前缀询问,第一次询问统计每个点的贡献,后面再直接弄即可。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<vector>
     4 #define N 100005
     5 using namespace std;
     6 vector<int>cs[2][N];
     7 int rt[2][N],a[N];
     8 long long ans;
     9 inline int read()
    10 {
    11     int x=0;char c=getchar();
    12     while(c<'0'||c>'9')c=getchar();
    13     while(c>='0'&&c<='9')x=x*10+c-48,c=getchar();
    14     return x;
    15 }
    16 struct Segtree{
    17     int ls[N<<6],rs[N<<6],s[N<<6],tot;
    18     void insert(int &k,int l,int r,int pos,int pre)
    19     {
    20         if(!k)k=++tot;
    21         if(l==r)
    22         {
    23             if(!s[k])s[k]=s[pre]+1;
    24             else s[k]++;
    25             return ;
    26         }
    27         int mid=l+r>>1;
    28         if(pos<=mid) 
    29         {
    30             if(!rs[k])rs[k]=rs[pre];
    31             if(ls[k]==ls[pre])ls[k]=++tot;
    32             insert(ls[k],l,mid,pos,ls[pre]);
    33         }
    34         else 
    35         {    
    36             if(!ls[k])ls[k]=ls[pre]; 
    37             if(rs[k]==rs[pre])rs[k]=++tot;
    38             insert(rs[k],mid+1,r,pos,rs[pre]);
    39         }
    40         s[k]=s[ls[k]]+s[rs[k]];
    41     }
    42     int query(int k,int l,int r,int ll,int rr)
    43     {
    44         if(l>=ll&&r<=rr) {return s[k];}
    45         int mid=l+r>>1;
    46         return (ll<=mid?query(ls[k],l,mid,ll,rr):0)+(rr>mid?query(rs[k],mid+1,r,ll,rr):0);
    47     }
    48 }T;
    49 int main()
    50 {
    51     int n=read(),m=read(),q=read();
    52     for(int i=1;i<=n;i++)a[i]=read();
    53     for(int i=1;i<=m;i++)
    54     {
    55         int l=read(),r=read(),x=read();
    56         cs[0][x].push_back(l-1),cs[1][x].push_back(r);
    57     }
    58     for(int i=1;i<=n;i++)
    59     {
    60         if(!cs[0][i].size()) rt[0][i]=rt[0][i-1],rt[1][i]=rt[1][i-1];
    61         for(int j=0;j<cs[0][i].size();j++) T.insert(rt[0][i],0,n,cs[0][i][j],rt[0][i-1]);
    62         for(int j=0;j<cs[1][i].size();j++) T.insert(rt[1][i],0,n,cs[1][i][j],rt[1][i-1]);
    63     }
    64     for(int i=1;i<=n;i++)
    65         ans+=T.query(rt[1][a[i]],0,n,i,n)-T.query(rt[0][a[i]],0,n,i,n);
    66     printf("%lld
    ",ans);
    67     while(q--)
    68     {
    69         int p=read()^ans,v=read()^ans;
    70         if(v<a[p])
    71             ans-=T.query(rt[1][a[p]],0,n,p,n),ans+=T.query(rt[1][v],0,n,p,n),
    72             ans+=T.query(rt[0][a[p]],0,n,p,n),ans-=T.query(rt[0][v],0,n,p,n);
    73         else if(v^a[p])
    74             ans+=T.query(rt[1][v],0,n,p,n),ans-=T.query(rt[1][a[p]],0,n,p,n),
    75             ans-=T.query(rt[0][v],0,n,p,n),ans+=T.query(rt[0][a[p]],0,n,p,n);
    76         a[p]=v;
    77         printf("%lld
    ",ans);
    78     }
    79     return 0;
    80 }
    View Code

    Lockey大神打的比较简单的打法:维护对每个位置的询问,差分+主席树维护前缀。

    具体来说:对于一个询问Q(l,r,x),先在l处把x询问++,在r+1处x询问--。

    一个一个插入主席树,再询问前缀,就能得到某点的询问,值得借鉴。

    还有$O(nlogn^2)$的线段树加vector,不再多说。

    T1 u

    差分题,只有2*n条斜线,直接差分维护。

     1 #include<cstdio>
     2 #define N 2005
     3 #define int long long
     4 using namespace std;
     5 int cf[N][N],gt[N][N],tot,fir[N][N],n;
     6 inline int _min(int a,int b){return a<b?a:b;}
     7 inline int read()
     8 {
     9     int x=0;char c=getchar();
    10     while(c>'9'||c<'0')c=getchar();
    11     while(c>='0'&&c<='9')x=x*10+c-48,c=getchar();
    12     return x;
    13 }
    14 void Get(int x,int y)
    15 {        
    16     fir[x][y]=cf[x][y];
    17     if(x+1>0&&y+1<=n)
    18     {
    19         cf[x+1][y+1]+=cf[x][y];
    20         Get(x+1,y+1);
    21     }
    22 }
    23 signed main()
    24 {
    25     n=read();
    26     int q=read(),ans=0;
    27     while(q--)
    28     {
    29         int r=read(),c=read(),l=read(),s=read();
    30         gt[r][c]+=s;
    31         gt[_min(r+l,n+1)][c]-=s;
    32         cf[r][c+1]-=s;
    33         cf[_min(r+l,n+1)][_min(c+l+1,n+1)]+=s;
    34     }
    35     for(int i=1;i<=n;i++)Get(1,i);
    36     for(int i=2;i<=n;i++)Get(i,1);
    37     for(int i=1;i<=n;i++)
    38         for(int j=1;j<=n;j++)
    39         {
    40             gt[j][i]+=gt[j-1][i];
    41             fir[j][i]+=gt[j][i];
    42         }
    43     for(int i=1;i<=n;i++)
    44         for(int j=1;j<=n;j++)
    45         {
    46             fir[i][j]+=fir[i][j-1];
    47             ans^=fir[i][j];
    48         }
    49     printf("%lld
    ",ans);
    50     return 0;
    51 }
    View Code

    T2 v

    典型状压题,记忆化一下AC,状态数我并不会证。

     1 #include<cstdio>
     2 #define mod 2333333
     3 using namespace std;
     4 struct Hushmap{
     5     int cnt,head[2400000],to[mod+1],nxt[mod+1];
     6     double id[mod+1];
     7     void insert(long long x,double p)
     8     {
     9         int k=x%mod;
    10         to[++cnt]=x,nxt[cnt]=head[k],id[cnt]=p,head[k]=cnt;
    11     }
    12     double find(long long x)
    13     {
    14         int k=x%mod;
    15         for(int i=head[k];i;i=nxt[i]) if(to[i]==x) return id[i];
    16         return -1;
    17     }
    18 }H[31];
    19 int n,k;
    20 char s[105];
    21 inline int gank(int x,int w)
    22 {
    23     int tmp=x&((1<<w)-1);
    24     x>>=(w+1);x<<=w;tmp|=x;
    25     return tmp;
    26 }
    27 inline double _max(double a,double b)
    28 {
    29     return a>b?a:b;
    30 }
    31 double dfs(int now,int st)
    32 {
    33     if(now==k+1) return 0;
    34     double jc=H[now].find(st);
    35     if(jc>=0)return jc;
    36     double tmp=0;
    37     for(int i=1;i<=n-now+1;i++)
    38     {
    39         int ot=n-now+2-i;
    40         double a,b;
    41         a=dfs(now+1,gank(st,i-1))+((st>>i-1)&1);
    42         b=dfs(now+1,gank(st,ot-1))+((st>>ot-1)&1);
    43         tmp+=_max(a,b)/(n-now+1);
    44     }
    45     H[now].insert(st,tmp);
    46     return tmp;
    47 }
    48 int main()
    49 {
    50     double ans=0;int st=0;
    51     scanf("%d%d",&n,&k);
    52     scanf("%s",s+1);
    53     for(int i=1;i<=n;i++)
    54     {
    55         int tmp=0;
    56         if(s[i]=='W')tmp=1;
    57         else tmp=0;
    58         st|=(tmp<<i-1);
    59     }
    60     printf("%.8lf
    ",dfs(1,st));
    61     return 0;
    62 }
    View Code

    T3 w

    暴力/乱搞可以搞到80分(数据水)

    正解是二元组DP,由于路径条数不好维护,维护奇数点,合并子树,分情况讨论即可。

     1 #include<bits/stdc++.h>
     2 #define N 200005
     3 #define INF 200001
     4 #define mp make_pair
     5 #define fir first
     6 #define sec second
     7 #define P pair<int,int>
     8 using namespace std;
     9 int to[N<<1],nxt[N<<1],head[N],cnt=1,col[N<<1],toc[N<<1],ans=0;
    10 pair<int,int>dp[N][2];
    11 inline void Add(int u,int v,int fr,int ty){to[++cnt]=v,nxt[cnt]=head[u],head[u]=cnt,col[cnt]=fr,toc[cnt]=ty;}
    12 inline int read()
    13 {
    14     int x=0;char c=getchar();
    15     while(c>'9'||c<'0')c=getchar();
    16     while(c>='0'&&c<='9')x=x*10+c-48,c=getchar();
    17     return x;
    18 }
    19 inline int _max(int a,int b){return a>b?a:b;}
    20 inline int _min(int a,int b){return a<b?a:b;}
    21 inline P add(P a,P b)
    22 {
    23     return mp(a.fir+b.fir,a.sec+b.sec);
    24 }
    25 void dfs(int x,int pre)
    26 {
    27     P w1=mp(INF,INF),w2=mp(0,0); 
    28     for(int i=head[x];i;i=nxt[i])
    29     {
    30         if(i==(pre^1))continue;
    31         int y=to[i];
    32         dfs(y,i);
    33         P tmp1=w1,tmp2=w2;
    34         w1=min(add(tmp1,dp[y][0]),add(tmp2,dp[y][1]));
    35         w2=min(add(tmp1,dp[y][1]),add(tmp2,dp[y][0]));
    36     }
    37     if(col[pre]==(toc[pre]^1)) dp[x][0]=mp(INF,INF),dp[x][1]=min(add(w1,mp(0,1)),add(w2,mp(1,1)));
    38     else if(col[pre]==toc[pre]) dp[x][1]=mp(INF,INF),dp[x][0]=min(add(w1,mp(1,0)),w2);
    39     else dp[x][1]=min(add(w1,mp(0,1)),add(w2,mp(1,1))),dp[x][0]=min(add(w1,mp(1,0)),w2);
    40     return ;
    41 }
    42 int main()
    43 {
    44     int n=read();
    45     for(int i=1,a,b,c,d;i<n;i++)
    46     {
    47         a=read(),b=read(),c=read()+2,d=read()+2,Add(a,b,c,d),Add(b,a,c,d);
    48         if(c==(d^1))ans++;
    49     }
    50     dfs(1,0);
    51     printf("%d %d
    ",dp[1][0].fir/2,dp[1][0].sec);
    52 }
    View Code
  • 相关阅读:
    视图集
    子类视图
    Mixin扩展类
    GenericAPIView
    APIView
    ModelSerializer使用
    序列化和反序列化
    合并购物车
    pyplot基本绘制
    STL sort “invalid operator <”
  • 原文地址:https://www.cnblogs.com/hzoi-kx/p/11602221.html
Copyright © 2011-2022 走看看