QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#470908 | #1436. Split in Sets | yz_ly | WA | 1ms | 3804kb | C++14 | 2.5kb | 2024-07-10 16:53:48 | 2024-07-10 16:53:49 |
Judging History
answer
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int f=1,x=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
inline void work(ll k){
if(k<0){
putchar('-');
k=-k;
}
if(k>9)
work(k/10);
putchar(k%10+'0');
}
/*
从高位向低位考虑
首先如果最高位全部相同,直接计算最高位贡献就行
设这一位的个数为c,如果c<m,就全部单独放一个盒子,继续计算其它数
如果c>=m则这一位为0的单独放一个盒子,把这些数合并成一个数,ans+=(1<<c)*(m-1),继续计算剩下的数
发现只有在考虑最后一位的时候需要计数,这里假设盒子相同,最后乘上一个m!就行了
c<m方案数为1,c>=m方案数为S(c+1,m),求解斯特林数就行了
*/
const ll mod=1e9+7;
int n,k;
ll ans,jc[100005],inv[100005],ans1;
vector<int> q;
ll power(ll a,ll b){
ll sum=1,k=a;
while(b){
if(b&1ll)
sum=sum*k%mod;
k=k*k%mod;
b>>=1ll;
}
return sum;
}
void solve(vector<int> q,int c,int m){
int num=0;
for(int i=0;i<q.size();i++){
if((q[i]>>c)&1)
num++;
}
vector<int> p;
if(num==q.size()){
for(int i=0;i<q.size();i++){
p.emplace_back(q[i]-(1<<c));
}
ans+=(1ll<<c)*m;
if(c)
solve(p,c-1,m);
else{
for(int i=0;i<=m;i++){
ans1=(ans1+((m-i)&1?-1:1)*inv[m-i]*inv[i]%mod*power(i,num)%mod)%mod;
}
}
}
else if(num<m){
for(int i=0;i<q.size();i++){
if((q[i]>>c)&1)
ans+=q[i];
else
p.emplace_back(q[i]);
}
if(c)
solve(p,c-1,m-num);
else{
for(int i=0;i<=m-num;i++){
ans1=(ans1+((m-num-i)&1?-1:1)*inv[m-num-i]*inv[i]%mod*power(i,p.size())%mod)%mod;
}
}
}
else{
int sum=(1<<30)-1;
for(int i=0;i<q.size();i++){
if((q[i]>>c)&1)
p.emplace_back(q[i]-(1<<c));
else
sum=(sum&q[i]);
}
p.emplace_back(sum);
ans+=(1ll<<c)*(m-1);
if(c)
solve(p,c-1,m);
else{
if(n>3)
cout<<"1.........\n";
for(int i=0;i<=m;i++){
ans1=(ans1+((m-i)&1?-1:1)*inv[m-i]*inv[i]%mod*power(i,num)%mod)%mod;
}
}
}
}
int main(){
n=read();
k=read();
for(int i=1;i<=n;i++){
q.emplace_back(read());
}
jc[0]=inv[0]=inv[1]=1;
for(int i=1;i<=n;i++){
jc[i]=jc[i-1]*i%mod;
}
for(int i=2;i<=n;i++){
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
for(int i=1;i<=n;i++){
inv[i]=inv[i-1]*inv[i]%mod;
}
solve(q,29,k);
work(ans);
putchar(' ');
work((ans1*jc[k]%mod+mod)%mod);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3604kb
input:
3 2 4 7 5
output:
11 2
result:
ok 2 tokens
Test #2:
score: 0
Accepted
time: 0ms
memory: 3804kb
input:
4 1 44 47 74 77
output:
8 1
result:
ok 2 tokens
Test #3:
score: 0
Accepted
time: 0ms
memory: 3524kb
input:
4 4 44 47 74 77
output:
242 24
result:
ok 2 tokens
Test #4:
score: -100
Wrong Answer
time: 1ms
memory: 3764kb
input:
1000 975 633065 7087 25267 3940676 618039 1695 2043 728466935 3498 13604984 4 99 119488 151315 12 32 52705062 26815 1902279 33952 480604 390647001 60 1 12566875 7591859 6 119892 7829822 2129 4 11644639 17 33200 5330 338 2 9 6862 3781 148087 57 198 13224999 10493180 1 5755424 216 1757297 210 1002623 ...
output:
1......... 35467198613 872149628
result:
wrong answer 1st words differ - expected: '35467198613', found: '1.........'