您的位置:首页 > 其它

【二分】【高精度】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的情况。

 

//
//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;
}

/*
//

//
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: