模拟测试49

Posted hzoi-kx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟测试49相关的知识,希望对你有一定的参考价值。

这次考试题还是蛮好的,只是人很水啊

T1

考场思路:

1.每次询问离线出来,再对于每一个k进行操作,klnk枚举区间,再利用主席树查前驱,期望时间复杂度O(n*log(n)^2)但可以被卡到(n^2*log(n))(对于k极小的询问),如果优化就把k极小的询问预处理?不可实现弃辽

2.分块,不会处理每一块的答案,死了

所以正解还是分块,考虑预处理每一块答案。

对于一个k来说,答案一定是maxi*k~i*k+k-1(0<=i<=n/k)中每一段的最大值%k,开一个桶维护每一块内的元素,扫一边搞出<=每个数的数直接处理即可。复杂度为O(n*ln(n)*n/S+m*S)当S取sqrt(n*log(n))的时候最小为O(n*sqrt(n*log(n)))

技术图片
 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #define N 100001
 5 #define sN 105
 6 using namespace std;
 7 inline int _max(int a,int b)return a>b?a:b;
 8 int bl[N+5],ans[sN][N+5],t[N+5],tl[N+5],tot,L[sN],a[N+5];
 9 inline int read()
10 
11     int x=0,f=1;char c=getchar();
12     while(c>9||c<0)if(c==-)f=-1;c=getchar();
13     while(c>=0&&c<=9)x=x*10+c-48,c=getchar();
14     return x*f;
15 
16 inline void pre()
17 
18     int now;
19     for(int i=1;i<=tot;i++)
20     
21         now=L[i];
22         while(bl[now]==i)t[a[now]]++,tl[a[now]]=a[now],now++;
23         for(int j=1;j<=N;j++)if(!t[j])tl[j]=tl[j-1];now=L[i];
24         for(int j=2;j<=N;j++)
25         
26             for(int k=j-1;k<=N;k+=j)
27                 ans[i][j]=_max(ans[i][j],(tl[k]%j));
28             ans[i][j]=_max(ans[i][j],(tl[N]%j));
29         
30         while(bl[now]==i)t[a[now]]--,tl[a[now]]=0,now++;
31     
32 
33 inline int query(int l,int r,int k)
34 
35     int mx=0;
36     if(bl[l]==bl[r])
37     
38         for(int i=l;i<=r;i++)mx=_max(mx,a[i]%k);
39         return mx;
40     
41     for(int i=l;bl[i]==bl[l];i++)mx=_max(mx,a[i]%k);
42     for(int i=bl[l]+1;i<bl[r];i++)mx=_max(mx,ans[i][k]);
43     for(int i=r;bl[i]==bl[r];i--)mx=_max(mx,a[i]%k);
44     return mx;
45 
46 int main()
47 
48     int n=read(),m=read();
49     int t=sqrt(n*20)+1;
50     for(int i=1;i<=n;i++)
51     
52         bl[i]=(i-1)/t+1;//printf("%d\n",bl[i]);
53         if(bl[i]!=bl[i-1])L[bl[i]]=i;
54         a[i]=read();
55     tot=bl[n];pre();
56     while(m--)
57     
58         int l=read(),r=read(),k=read();
59         printf("%d\n",query(l,r,k));
60     
61     return 0;
62 
View Code

T2

n^2思路很简单,但是会被卡空间。

所以换个角度,按x排序。

实际上就是找不断往中间收缩的方案数(感性理解)

考虑处理出前i-1个如何弄第i个,设dp[i][0/1]表示以i为起点往左/右走的方案数

如果i是起点,那么给i加上前面比它小的往右撇的方案即可

如果不是,那么i一定是第二个点,枚举起点和第三个点,给起点加上第三个点的贡献。

得出转移方程:

dp[i][0]+=dp[j][1];(j<i&&y[j]<y[i])

dp[j][1]+=dp[z][1];(j<i&&z>j&&z<i&&y[z]<y[j]&&y[j]<y[i])

技术图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #define FH_SB 6005
 4 using namespace std;
 5 const int mod=1e9+7;
 6 int dp[FH_SB][2],s[FH_SB];
 7 struct node
 8     int fh,sb;
 9     inline void init()scanf("%d%d",&fh,&sb);
10     friend bool operator <(const node a,const node b) return a.fh<b.fh;
11 a[FH_SB];
12 int main()
13 
14     int n,ans=0;scanf("%d",&n);
15     for(int i=1;i<=n;i++)a[i].init();
16     sort(a+1,a+n+1);
17     for(int i=1;i<=n;i++)
18     
19         s[i]=1;dp[i][0]++;dp[i][1]++;
20         for(int j=i-1;j;j--) s[j]=(s[j+1]+dp[j][1]*(a[j].sb<a[i].sb))%mod;
21         for(int j=1;j<i;j++)
22         
23             if(a[j].sb<a[i].sb)(dp[i][0]+=dp[j][1])%=mod;
24             else (dp[j][1]+=s[j+1])%=mod;
25         
26     
27     for(int i=1;i<=n;i++)(ans+=(dp[i][0]+dp[i][1])%mod)%=mod;
28     printf("%d\n",ans-n);
29 
View Code

 

T3不会,咕了。

 

以上是关于模拟测试49的主要内容,如果未能解决你的问题,请参考以下文章

[考试反思]0921csp-s模拟测试49:困顿

在单元测试中模拟 IHttpContextAccessor

测试模拟关闭网络 iPad 测试仪 iOS

iOS单元测试私有模拟对象?

测试 Vue 组件 - 模拟状态和方法

XCode UITest:测试运行时模拟器不可见