NOIP2017提高组 模拟赛15(总结)
2017-09-13 13:29
357 查看
NOIP2017提高组 模拟赛15(总结)
第一题 讨厌整除的小明
【题目描述】
【解题思路】
其实就是求2T≤n中最大的T值,答案即为T+1。为什么?
列个次方表:
次方 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
2 | 1 | 2 | 4 | 8 | 16 | 32 |
3 | 1 | 3 | 9 | 27 | 81 | 243 |
5 | 1 | 5 | 25 | 125 | 625 | 3125 |
设合数X=p1k1∗p2k2∗p3k3∗……∗pnkn
X可以放在第(k1+k2+k3+……+kn)列里,则一定不会有倍数关系。
因为自然数X分解成质因数只会有一种方案。
假设Y=KX(K>1),且X,Y在同一列。
那么∑p(Y)=∑p(K)+∑p(X),K>1所以∑p(K)>0。
所以X,Y不可能在同一列。
又可以知道∑q≤T。(最大的次方数不超过T)
求出T即可。时间复杂度O(q log n)
【代码】
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; int T; ll n; int main() { freopen("2057.in","r",stdin); freopen("2057.out","w",stdout); scanf("%d",&T); while(T--) { scanf("%lld",&n); int s=0; while(n) { n>>=1; s++; } printf("%d\n",s); } return 0; }
第二题 山高 (原题 bzoj3193 地形生成)
【题目描述】
【解题思路】
假如没有相同高度的山就好做了……题目的si是小于,si–,化成小于等于。
先从大到小排序,高度hi相等的关键字si小的在前。
先把同一高度的提取出来。
对于一段高度相同的山,第1个为i,最后一个为t。
先考虑第一个答案:
那么第j(i≤j≤t)座山可选取的范围就是min(i,sj+1)+j-i,所有的山的范围乘起来就是答案。
1 2 3 4 5…i…j…t,j可以放在i之前的山(它们都高过j)的后面,一共有i种(第0座山到第i-1座山的后面,还要和sj+1取min),还可以放在相等的山的后面,也就是j-i。所以山j的范围是min(i,sj+1)+j-i。
考虑第二个答案:
因为相同的山即使标号不同也只记做一种方案。
所以,相同的山一定是从前往后放的。也就是相同的山i,i+1,i一定放在i+1之前。
列出dp方程:dp[i][j]表示第i个相同的山,放在第j个山(之前的山,不与当前山等高)的后面的方案数。
dp[i][j]=∑jk=0dp[i−1][k]
j是有序的,也就是si。
可以用前缀和优化,dp[i][j]=dp[i][j-1]+dp[i-1][j];
f[j]=dp[1~i][j],表示当前山放在第j座山后面的方案数。
f[j]=f[j]+f[j-1];
【代码】
#include<cstdio> #include<algorithm> #define imin(a,b) ((a<b)?(a):(b)) using namespace std; typedef long long ll; const int N=1200; const int mods=2011; int n,ans1,ans2,f ; struct data { int h,s; } d ; bool cmp(data A,data B) { return (A.h>B.h || (A.h==B.h && A.s<B.s)); } int main() { freopen("2239.in","r",stdin); freopen("2239.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&d[i].h,&d[i].s),d[i].s--; sort(d+1,d+1+n,cmp); ans1=ans2=1; for(int i=1;i<=n;) { int t=i,mk; while(d[t+1].h==d[t].h && t<n) t++; for(int j=1;j<=n;j++) f[j]=0; f[0]=1; for(int j=i;j<=t;j++) { ans1=ans1*((imin(i,d[j].s+1)+j-i)%mods)%mods; mk=imin(i-1,d[j].s); for(int k=1;k<=mk;k++) f[k]=(f[k]+f[k-1])%mods; } int tmp=0; mk=imin(i-1,d[t].s); for(int j=0;j<=mk;j++) tmp=(tmp+f[j])%mods; ans2=ans2*tmp%mods; i=t+1; } printf("%d %d\n",ans1,ans2); return 0; }
第三题 ABA字符串 (原题 bzoj3620 似乎在梦中见过的样子)
【题目描述】
【解题思路】
暴力O(n²)的KMP,没什么好说的……(其实是懒得写了)【代码】
#include<cstring> #include<algorithm> #include<cstdio> using namespace std; const int N=10010; char sd ,*st; int n,m,ans; int ne ,mi ; int main() { freopen("2240.in","r",stdin); freopen("2240.out","w",stdout); scanf("%s",sd); scanf("%d",&m); n=strlen(sd); st=sd; int nt=n; for(int w=1;w<nt;w++) { ne[0]=ne[1]=mi[0]=mi[1]=0; int k=0; for(int i=2;i<=n;i++) { while(k>0 && st[i-1]!=st[k]) k=ne[k]; if(st[i-1]==st[k]) k++; ne[i]=k; mi[i]=k; if(mi[ne[i]]>=m) mi[i]=mi[ne[i]]; if(mi[i]>=m && (mi[i]<<1)<i) ans++; } st=st+1; n--; } printf("%d\n",ans); return 0; }
相关文章推荐
- 2017.04.15【NOIP2017提高组】模拟赛B组总结
- NOIP2017提高组 模拟赛13(总结)
- NOIP2017提高组 模拟赛21(总结)
- NOIP2017提高组 模拟赛23(总结)
- 2017.04.15【NOIP2017提高组】模拟赛B组 总结
- NOIP2017提高组 模拟赛 27(总结)
- NOIP2017提高组 模拟赛 26(总结)
- NOIP2017提高组 模拟赛17(总结)
- NOIP2017提高组模拟赛 7(总结)
- NOIP2017提高组 模拟赛18(总结)
- NOIP2017提高组 模拟赛24(总结)
- 2016.5.21【初中部 NOIP提高组 】模拟赛A 总结
- noip2017提高组小结兼期中考试总结
- 2017.08.18【NOIP提高组】模拟赛B组总结
- 【NOIP2017提高A组模拟10.10】总结
- 【NOIP2017提高A组冲刺11.7】总结
- 2016.6.11【初中部 NOIP提高组 】模拟赛C 总结
- 2016.5.14【初中部 NOIP提高组 】模拟赛C总结
- 【NOIP2017提高A组集训10.21】 总结
- 2016.5.21【初中部 NOIP提高组 】模拟赛A 总结