【二分】【高精度】Vijos P1472 教主的集合序列
2016-08-16 23:35
441 查看
题目链接:
https://vijos.org/p/1472
题目大意:
S1={1,2,3…n}。当i>1时,Si为集合Si-1中任意两个不相同数之和的集合。
将每个集合中所有元素取出,集合Si的数放在集合Si+1的数的前面,同一个集合数从小到大排序,这样得到一个序列L。
题目输入n和K,求L中第K个数是多少。
变态的数据范围:K≤101000,1<n≤1000;且数据保证当n≤3时,K≤900000。
题目思路:
【二分】【高精度】
真是恶心的一道题啊。。打了好久。
S1={1,2,...,n}
S2={3,4,...,2n-1}
S3={7,8,...,4n-3}
S4={15,16,...,8n-7}
S5={31,32,...,16n-15}
......
Sk={2k-1,2k,...,n*2k-1-2k-1+1}={2k-1,2k,...,(n-1)2k-1+1}
所以第k个集合的大小为(n-1)*2k-1-2k+3
前k个集合总数为(n-3)*2k+3(k+1)-n
二分目标数处在第几个集合,然后简单运算并输出即可。注意n=1,2,3的情况。
https://vijos.org/p/1472
题目大意:
S1={1,2,3…n}。当i>1时,Si为集合Si-1中任意两个不相同数之和的集合。
将每个集合中所有元素取出,集合Si的数放在集合Si+1的数的前面,同一个集合数从小到大排序,这样得到一个序列L。
题目输入n和K,求L中第K个数是多少。
变态的数据范围:K≤101000,1<n≤1000;且数据保证当n≤3时,K≤900000。
题目思路:
【二分】【高精度】
真是恶心的一道题啊。。打了好久。
S1={1,2,...,n}
S2={3,4,...,2n-1}
S3={7,8,...,4n-3}
S4={15,16,...,8n-7}
S5={31,32,...,16n-15}
......
Sk={2k-1,2k,...,n*2k-1-2k-1+1}={2k-1,2k,...,(n-1)2k-1+1}
所以第k个集合的大小为(n-1)*2k-1-2k+3
前k个集合总数为(n-3)*2k+3(k+1)-n
二分目标数处在第几个集合,然后简单运算并输出即可。注意n=1,2,3的情况。
// //by coolxxx // #include<iostream> #include<algorithm> #include<string> #include<iomanip> #include<memory.h> #include<time.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stdbool.h> #include<math.h> #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define abs(a) ((a)>0?(a):(-(a))) #define lowbit(a) (a&(-a)) #define sqr(a) ((a)*(a)) #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) #define eps 1e-8 #define J 10000000 #define MAX 0x7f7f7f7f #define PI 3.1415926535897 #define N 1007 #define M 10007 using namespace std; typedef long long LL; int cas,cass; int n,m,lll,ans; LL k[M]; char ch ; void gjdprint(LL a[]) { int i; printf("%lld",a[a[0]]); for(i=a[0]-1;i;i--) printf("%07lld",a[i]); puts(""); } int gjdcompare(LL a[],LL b[])//-1:a=b 0:a<b 1:a>b { int i; if(a[0]!=b[0])return a[0]>b[0]; for(i=a[0];i;i--) if(a[i]!=b[i])return a[i]>b[i]; return -1; } void gjdcheng(LL a[],LL b[],LL c[]) { LL t[M]={0}; int i,j; t[0]=a[0]+b[0]; for(i=1;i<=a[0];i++) for(j=1;j<=b[0];j++) t[i+j-1]+=a[i]*b[j]; for(i=1;i<=t[0];i++) t[i+1]+=t[i]/J,t[i]%=J; while(t[t[0]+1])t[0]++; while(!t[t[0]] && t[0]>1)t[0]--; memcpy(c,t,sizeof(t)); } void gjdquickpow(LL a[],LL x) { LL t[M]={1,2,0}; a[0]=a[1]=1; while(x) { if(x&1) { gjdcheng(a,t,a); } gjdcheng(t,t,t); x>>=1; } } void gjdchange(char s[],LL a[]) { int i,j,l; l=strlen(s); for(i=l,a[0]=1;i>6;i-=7,a[0]++) { for(j=0;j<7;j++) a[a[0]]=a[a[0]]*10+s[i-7+j]-'0'; } for(j=0;j<i;j++) a[a[0]]=a[a[0]]*10+s[j]-'0'; } void gjdjia(LL a[],LL b[],LL c[]) { int i; LL t[M]={0}; t[0]=max(a[0],b[0]); for(i=1;i<=t[0];i++) t[i]=a[i]+b[i]; for(i=1;i<=t[0];i++) t[i+1]+=t[i]/J,t[i]%=J; while(t[t[0]+1])t[0]++; while(!t[t[0]] && t[0]>1)t[0]--; memcpy(c,t,sizeof(t)); } void gjdjian(LL a[],LL b[],LL c[]) { int i; LL t[M]={0}; t[0]=a[0]; for(i=1;i<=t[0];i++) t[i]=a[i]-b[i]; for(i=1;i<t[0];i++) if(t[i]<0)t[i+1]--,t[i]+=J; while(!t[t[0]] && t[0]>1)t[0]--; memcpy(c,t,sizeof(t)); } void gjdchu2(LL a[]) { int i; for(i=a[0];i>1;i--) { if(a[i]&1)a[i-1]+=J; a[i]>>=1; } a[1]>>=1; while(!a[a[0]] && a[0]>1)a[0]--; } void getsum(LL t[],LL mid,LL tt[]) { gjdquickpow(t,mid-1); tt[1]=n-3; gjdcheng(t,tt,t); tt[1]=mid*3; gjdjia(t,tt,t); tt[1]=n; gjdjian(t,tt,t); } void work() { int i,j,l,r,mid; LL t[M]={0},tt[M]={1,0}; l=1;r=4000; while(l<r) { mid=(l+r+1)>>1; getsum(t,mid,tt); j=gjdcompare(k,t); if(j==-1) { gjdquickpow(t,mid-2); tt[1]=n-1; gjdcheng(t,tt,t); tt[1]=1; gjdjia(t,tt,t); gjdprint(t); return; } if(j)l=mid; else r=mid-1; } getsum(t,r,tt); gjdjian(k,t,k); gjdquickpow(t,r); tt[1]=2; gjdjian(t,tt,t); gjdjia(k,t,t); gjdprint(t); } int main() { #ifndef ONLINE_JUDGE // freopen("1.txt","r",stdin); // freopen("2.txt","w",stdout); #endif int i,j; // while(~scanf("%s",s1)) // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) while(~scanf("%d",&n)) { memset(k,0,sizeof(k)); if(n<4) { scanf("%d",&m); if(n==1) { if(m==1)puts("1"); else puts("-1"); } else if(n==2) { if(m==1)puts("1"); else if(m==2)puts("2"); else if(m==3)puts("3"); else puts("-1"); } else if(n==3) { gjdquickpow(k,(m+2)/3); if(m%3==1)k[1]--; else if(m%3==0)k[1]++; gjdprint(k); } continue; } scanf("%s",ch); gjdchange(ch,k); if(k[0]==1 && k[1]<=n) { gjdprint(k); continue; } work(); } return 0; } /* // // */
相关文章推荐
- 【二分】【高精度】Vijos P1472 教主的集合序列
- [jzoj1408][vijos1472] 教主的集合序列
- 【动态规划】【二分】【最长上升子序列】Vijos P1028 魔族密码
- 【动态规划】【二分】【最长上升子序列】Vijos P1028 魔族密码
- 两个有序序列的中位数(二分搜索)
- Oracle知识点总结—集合操作和序列
- leetcode 209. Minimum Size Subarray Sum-子序列最小长度|双指针|二分查找
- 类似最集合中最大子序列 hdu 2668
- hdu 5248 序列变换(二分+贪心)
- 单调递增最长子序列DP+二分
- hdu 5248 序列变换【二分】
- 【bzoj3173】【Tjoi2013】【最长上升子序列】treap+dp二分优化
- 百度之星2015初赛(1)1003 HDOJ5248 序列变换(二分 贪心)
- 高精度二分搜索
- LIS - 最长上升子序列 (二分优化)
- Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)
- 最长递增子序列!!!(DP ,二分)
- Vijos1450 包裹快递[二分答案]
- Vijos-2164 神秘的咒语 [LCIS最长公共上升子序列]
- 最长上升子序列(O(n^2)与O(nlogn)+二分)最长公共子序列