[破碎的状态] 101630K
题意:
给你n个数
保证:
a1<a2
a1+a2<a3
a1+a2+a3<a4
......
a1+...+an-1 < an
以及a1 + ... + an < q
现在我们选出了一个数字r,保证gcd(r,q)=1
bi = ai * r
那么当我们要发送一个长度为n的01信息给某人,我们可以发送一个bi的对应位置的和(对q取模)过去
例如11 49 100 发送149表示011(但是b数组不保证a数组的性质)
如果q是120的话,发送29表示011
现在选定q = 2^64
现在给你b,给你发送的数字
知道r的人可以自己通过r-1来求出相应的信息从而得出结论,但你没有r,你也要求出这个信息.
思路:
考虑n<=40的时候
我们分成两部分,每个部分都是20以内的,暴力
然后一个部分怎么选,我们可以利用和的性质去看另一部分是否满足
n>40的时候,我们可以发现
a1的值应该是很小的,一定在2^25以内
我们可以直接枚举这个值
然后根据 r-1 * a1 = i反推出r-1
r-1 = i * a1-1
但是这样直接得出结论会错,因为如果a1是2的倍数你就求不出来对应的r-1
如果a1这个值是2^k的倍数,那么我们可以求出a1/2^k的逆元;但是这时候因为i是2^k的倍数
所以我们考虑两边都除以2^k,上述式子就能成立,但是就不是%2^64了而是%2^(64-k)
那么我们应该有2^k个解,我们也分别枚举出来就行
代码:
#include<set> #include<map> #include<list> #include<queue> #include<stack> #include<string> #include<math.h> #include<time.h> #include<vector> #include<bitset> #include<memory> #include<utility> #include<fstream> #include<stdio.h> #include<sstream> #include<iostream> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; unsigned long long b[65]; unsigned long long c[65]; unsigned long long power(unsigned long long x,unsigned long long y) { if (y==0) return 1ull; unsigned long long t=power(x,y/2); t=t*t; if (y%2==1) t=t*x; return t; } bool over(unsigned long long x,unsigned long long y) { int i; for (i=63;i>=0;i--) { if (((1ull<<i)&x)^((1ull<<i)&y)) continue; if ((1ull<<i)&x) return true; else return false; } return false; } int main() { #ifdef absi2011 freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif int n; cin>>n; int i; for (i=0;i<n;i++) { cin>>b[i]; } unsigned long long a; cin>>a; if (n<=40) { map<unsigned long long,int> ma; int j; int t=(n/2); for (j=0;j<(1<<t);j++) { int k; unsigned long long cnt=0; for (k=0;k<t;k++) { if ((1<<k)&j) cnt+=b[k]; } ma[cnt]=j; } int l=n-t; for (j=0;j<(1<<l);j++) { int k; unsigned long long cnt=0; for (k=0;k<l;k++) { if ((1<<k)&j) cnt+=b[k+t]; } if (ma.find(a-cnt)!=ma.end()) { int i; for (i=0;i<t;i++) { if ((1<<i)&ma[a-cnt]) printf("1"); else printf("0"); } for (i=0;i<l;i++) { if ((1<<i)&j) printf("1"); else printf("0"); } printf("\n"); } } } else { int i; unsigned long long val; for (i=0;i<64;i++) { if (b[0]&(1ull<<i)) { val=power(b[0]>>i,(1ull<<63)-1); break; } } int temp=i; for (i=1;i<(1<<(65-n-temp));i++) { unsigned long long tt=val*i; unsigned long long t2; for (t2=0;t2<(1ull<<temp);t2++) { unsigned long long t=tt^(t2<<(64-temp)); int j; unsigned long long sum=0; for (j=0;j<n;j++) { c[j]=b[j]*t; if (c[j]<sum) break; if (over(sum,c[j])) break; sum+=c[j]; } if (j!=n) continue; a*=t; string ans; for (j=n-1;j>=0;j--) { if (a>=c[j]) { a-=c[j]; ans="1"+ans; } else { ans="0"+ans; } } cout<<ans<<endl; return 0; } } } return 0; }
Aug 20, 2022 02:02:56 AM
NJMCdirect – the fast, secure and convenient way to access and pay your Traffic Ticket and Municipal Complaint online. njmcdirect To view or pay your Traffic 2021. NJMCDirect Pay Traffic Tickets Online – www.NJMCDirect.com · What is NJMCDirect? · NJMCDirect Pay – What will you need to pay njmcdirect ticket payment 2021.