模拟测试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
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
T3不会,咕了。
以上是关于模拟测试49的主要内容,如果未能解决你的问题,请参考以下文章