玲珑学院OJ 1095 Six and One【暴力预处理+剪枝+二分查询】
来源:互联网 发布:济宁淘宝培训 编辑:程序博客网 时间:2024/05/22 17:13
Time Limit:1s Memory Limit:128MByte
Submissions:128Solved:28
Given the integers LL and RR, your task is calculating the count of the integer nn which meet the following conditions:
For instance, 11,66,1616,3636,6161,37213721 are some integers which meet the conditions.
ai是由6和1组成的数字,需要保证ai<=1e10
现在给你一个区间【l,r】,让你求一共有多少个N,使得L<=N<=R.
这里N表示是由若干个ai相乘得到的,N<=1e10
思路:
1、观察到T很大,明显是要考察O(1)查询或者是O(logn)查询的能力。
二分查询的考察肯定是比较套路的。
所以我萌需要进行预处理答案。
2、估计了一下,长度为1的有6和1,长度为2的有11 16 66 61.那么很明显,预处理出从长度1到长度为10的ai.一共也就是有2046个.
那么我们接下来考虑找寻组合,使得相乘得到的数小于1e10.
我们不妨在纸上简单的处理一些数据,不难发现,当取出来的数的个数大于等于4的时候,情况就变得非常少了。
那么我们Dfs暴力处理,做好剪枝,肯定不会超时。
这里需要注意几点:
①我们最多可能取很多数出来,6^12的得数是小于1e10的.所以我们最多可能要取12个数。
②我们还要对数组进行去重。
③Dfs过程中处理不当可能会出现爆LL的可能,所以我们在相乘两个数的时候,要在长度上进行预估。
3、接下来对于查询,我们找第一个大于l的数出现的位子posl,找第一个小于r的数出现的位子posr,预处理得到的可能的N一共有6w+数,直接枚举找位子肯定是要超时的,所以我们对这6W个数进行排序,然后二分这两个位子,那么ans=posr-posl;
Ac代码:
#include<bits/stdc++.h>using namespace std;#define ll long long intll ans[1000050];ll anstmp[1000050];int cnt;void Dfs(ll nw,int len){ ans[cnt++]=nw; if(len+1<=10) Dfs(nw*10+1,len+1); if(len+1<=10) Dfs(nw*10+6,len+1);}int lenn(ll a){ int re=0; while(a) { a/=10; re++; } return re;}void Dfs_getnum(ll nw,int ned,int hav,int pos){ if(ned==hav) { ans[cnt++]=nw; return ; } if(pos<=2046&&nw*ans[pos]>10000000000||lenn(nw)+lenn(ans[pos])>11)return ; for(int j=pos;j<=2046;j++) { if(nw*ans[j]>10000000000||lenn(nw)+lenn(ans[j])>11)break; else { Dfs_getnum(nw*ans[j],ned,hav+1,j); } }}void init(){ cnt=0; Dfs(1,1); Dfs(6,1); sort(ans,ans+cnt); ll test=1; for(int i=2;i<=13;i++) { for(int j=0;j<cnt;j++) Dfs_getnum(ans[j],i,1,j); } sort(ans,ans+cnt); for(int i=0;i<cnt;i++)anstmp[i]=ans[i]; int tmpcnt=cnt; cnt=0; for(int i=0;i<tmpcnt;i++) { if(anstmp[i]==anstmp[i+1])continue; else { ans[cnt++]=anstmp[i]; } }}int main(){ init(); int t; scanf("%d",&t); while(t--) { ll tmpl,tmpr; scanf("%lld%lld",&tmpl,&tmpr); int ansl=-1; int l=0; int r=cnt; while(r-l>=0) { int mid=(l+r)/2; if(ans[mid]>=tmpl) { ansl=mid; r=mid-1; } else l=mid+1; } int ansr=-1; l=0; r=cnt; while(r-l>=0) { int mid=(l+r)/2; if(ans[mid]<=tmpr) { ansr=mid; l=mid+1; } else r=mid-1; } if(ansl==-1||ansr==-1) { printf("0\n"); } else printf("%d\n",ansr-ansl+1); }}
- 玲珑学院OJ 1095 Six and One【暴力预处理+剪枝+二分查询】
- 玲珑杯 Six and One 【暴力】
- DP+预处理优化——玲珑学院OJ 1108
- 玲珑学院OJ 1014 - Absolute Defeat(智商暴力题)
- 玲珑学院OJ 1015 Better Days Ahead【暴力粗奇迹】
- 玲珑学院OJ 1096 萌萌哒的第一题【暴力】
- 玲珑学院OJ 1126
- 玲珑学院OJ 1125
- 玲珑学院OJ 1131
- 玲珑学院OJ 1121
- 玲珑学院OJ 1130
- 倍增二分——玲珑学院OJ #1112
- 玲珑学院OJ 1149-Buildings-(RMQ+二分)
- 玲珑学院oj Round#7
- 玲珑学院OJ 1132 Down the Rabbit Hole【Dfs序+暴力】
- 玲珑学院OJ 1129 喵哈哈村的战斗魔法师丶坏坏い月【暴力分块】
- 玲珑学院OJ 1017 Don't You Want Me?【枚举+二分】
- [玲珑学院OJ 1029 - Bob and Alice are playing factors]Miller_Rabin+Pollard_rho+排列组合+逆元
- Bootstrap table 刷新回调陷入死循环
- MongoDB中distinct的详细用法
- Android系统架构
- 静态库和动态库
- 文件系统 Proc
- 玲珑学院OJ 1095 Six and One【暴力预处理+剪枝+二分查询】
- android Activity的 theme
- Mecanim Animator使用详解
- 初级背包模板
- Spark相关参数详细说明网址
- 理解MySQL——复制(Replication)
- Android 面试精华题目总结
- MySQL之选择字段数据类型
- #Paper Reading# Curriculum Learning