模拟测试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\n",l);
52     return 0;
53 }

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\n",ans);
56 }

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\n",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\n",ans);
78     }
79     return 0;
80 }

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

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

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

还有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\n",ans);
50     return 0;
51 }

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\n",dfs(1,st));
61     return 0;
62 }

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\n",dp[1][0].fir/2,dp[1][0].sec);
52 }

原文地址:https://www.cnblogs.com/hzoi-kx/p/11602221.html

时间: 2024-10-30 07:54:43

模拟测试52,53反思的相关文章

2019.9.26 csp-s模拟测试52 反思总结

刚刚写了一个小时的博客没了,浏览器自动刷新. 一!个!小!时! 鼠标键盘电脑哪个都不能摔,气死我了. 垃圾选手T1T2没思路,T3倒是想出来得比较早,靠T3撑着分数. 数据结构学傻选手,属实垃圾. T1平均数: 一个序列的所有数如果减去x,那么平均数也会减去x.可以二分这个x,统计序列里平均数小于0的序列的个数,含义为原序列平均数小于x的序列的个数.最后统计值小于k且最接近k的x就是所求答案. 序列的平均数小于0,那么序列的和也一定小于0.表现在前缀和上即为一个区间的sumr<suml-1,转化

csp-s模拟测试52平均数,序列题解

题面:https://www.cnblogs.com/Juve/articles/11602244.html 平均数: 第k个平均数不好求,我们考虑二分,转化成平均数小于x的有几个 虑把序列中的每个数减去 x,则我们只需求区间和小于 0 的区间数量. 我们对这个序列求前缀和,则区间[L,R]和小于 0 当且仅当 SL-1>SR, 答案即为前缀和序列 S 的逆序对数量,使用经典的归并排序即可解决 #include<iostream> #include<cstdio> #incl

[考试反思]0929csp-s模拟测试55:沦陷

菜得过分. 面对T1的大板子不知所措,然后T2的贪心不小心把排序语句删了... T1这种大模板啊...其实我是觉得我能打出来的,然后先用一个小时码了一个2k. 然后做T2想贪心就出来了.十分钟码完T3暴力之后回T1打对拍瞬间爆炸. 于是又重新打了一个2k,WA0.对拍发现. 然后考试就没几分钟了交暴力走了. 不要打完就跑,记得早点对拍改进思路. T1: 的确是挺裸的线段树.离散化或者权值线段树都可以. 但是考场上两个都打出来都死了. 最后用离散化A的. 1 #include<cstdio> 2

[考试反思]1003csp-s模拟测试58:沉淀

稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使用的话,切记计算内存,一点都不能开大. T1: 直接根号筛,拿map也能过. 遍历map直接begin和end啊... 1 #include<cstdio> 2 int Cnt[202]; 3 struct hash_map{ 4 int cnt,fir[10000020],l[6666666],

[考试反思]1002csp-s模拟测试56:凌乱

放假回来状态回升??(玩够了-但是稍困) T1打的不完全对,但是过掉了.很快的想到了二分吧喇叭啦.. 然后T2也挺快想出来了但是挂细节没发现,考试快结束的时候才发现出锅了. 改了过来是正解,但是出题人无良卡了线段树强制树状数组,T了一个子任务,卡常到飞起. T3暴力没什么问题. 卡常是一种习惯.要注意题目数据范围观察是否卡常. T1: 所有的决策都是一条一次函数. 分两类,斜率正或斜率非负. 如果第二类的直线里有在T=0时符合要求的,那么答案就是0,所以check(0)一下. 如果非负的直线都在

csps模拟测试50反思

又考崩了,T1一眼秒掉错误思路,然后迅速码完,并码完错误暴力,对拍拍上,以为AC.T2想到了二维莫队,发现是子任务就没去打,一直在想别的,T3最后想到60分打法,没有打完,也没时间暴力,挂掉.T2还有一个读错题的锅,T了一个子任务. 考试一定要合理分配时间,确定自己算法的正确性,想到一个类似的算法要敢于去实现. T1 施工 单调栈优化dp 改变dp定义是优化dp的重要方式 dp[i]表示第i个位置不变的最优答案.枚举j转移,O(n^2),期望得分53 考虑优化,dp[i]只会由最多一个h比它大的

微信在线信息模拟测试工具(基于Senparc.Weixin.MP)

目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具在线DEMO:http://weixin.senparc.com/SimulateTool Senparc.Weixin.MP是一个开源的微信SDK项目,地址:https://github.com/JeffreySu/WeiXinMPSDK (其中https://github.com/Jeffrey

noip模拟测试11

T1:string 第一眼秒出思路,这不就是排序那道题的加强版吗? 然而歪?解复杂度虽然是对的,但常数过大,竟被卡到70 歪?解:(实际上std写的就是这个,但据说std被卡掉了 OAO) 因为字符集很小,所以我们可以把区间排序改为区间查询和覆盖 即:先查询区间内所有字符的个数,再从左端点开始按照大小关系依次将长度为字符个数的区间修改为该字符. 期望复杂度O ( 26*mlogn ),实际复杂度O ( 26*mlogn*(巨大的常数) ) 所以需要一(feng)定(kuang)的卡常 正?解:

2018.8.6 Noip2018模拟测试赛(十九)

日期: 八月六号  总分: 300分  难度: 提高 ~ 省选    得分: 10分(MMP) 题目目录: T1:Tree T2:异或运算 T3:Tree Restoring 赛后反思: Emmmmmmm…… 一直在打第一题…… 结果考完才发现dp少了一种情况…… 除此之外,我无话可说…… Emmmmmm…… 题解: T1:Tree 树形背包dp,设$f[i][j][k(0/1/2)]$为$i$的子树中,选$j$条边,0:从$i$出发,到$i$结束/1:从$i$出发,到$i$的某个后代结束/2: