QOJ.ac
QOJ
ID | Submission ID | Problem | Hacker | Owner | Result | Submit time | Judge time |
---|---|---|---|---|---|---|---|
#1533 | #876475 | #9685. nim 游戏 | Milmon | ChiFAN | Failed. | 2025-02-07 18:47:52 | 2025-02-07 18:47:52 |
Details
Extra Test:
Accepted
time: 1058ms
memory: 285764kb
input:
0 2 99999 10000 693815752492509729 11925695330427935 747684554686995239 803279038855367859 344738646601998652 1067454043680475010 336196020408586931 1083060110962364131 624721655924115772 414425100111495500 29209192369196689 1076166864122169125 969643129527148414 823547543591140066 90146493884927027...
output:
71079758861913 10000 30 1625 3741 8012 8638 9795 15490 18123 20774 26388 29477 29947 33938 34954 38124 39407 44985 48068 49800 51701 57779 64910 65909 66596 73577 78099 89123 89781 93463 95793 96547 2 15116192 1 37 19543815 299862852 1 1 2188 1 63337927202 1 1 1 3393503 8086810853 1 412 2532482 704...
result:
ok correct answer
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#876475 | #9685. nim 游戏 | ChiFAN | 97 | 1123ms | 311944kb | C++14 | 7.6kb | 2025-01-30 21:42:59 | 2025-02-07 20:37:28 |
answer
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5+114;
const int inf = 5e18;
int n,m,a[maxn],A[maxn],tim[maxn];
int keep(int id,int k){
//a[id] [0,k)
return (a[id]&((1ll<<k)-1));
}
int b[maxn];
int sum[65];
int ans;
int head[65],tail[65];
int tot;
int nxt[maxn*65],lst[maxn*65];
int dnxt[maxn][65],dlst[maxn][65];
int id[maxn][65];
int pos[maxn*65];
bool cmp(int x,int y){
return b[x]<b[y];
}
void init(){
for(int i=1;i<=n;i++) tim[i]=-1;
for(int i=0;i<61;i++){
vector<int> vec;
for(int j=1;j<=n;j++){
if(!((1ll<<i)&a[j]))
vec.push_back(j),b[j]=(1ll<<i)-keep(j,i);
}
for(int j=1;j<=n;j++){
if((1ll<<i)&a[j]) sum[i]++;
}
sort(vec.begin(),vec.end(),cmp);
head[i]=++tot;
for(int j=1;j<=n;j++) id[j][i]=++tot,pos[tot]=j;
tail[i]=++tot;
int lste=head[i];
for(int x:vec){
nxt[lste]=id[x][i];
lst[id[x][i]]=lste;
lste=id[x][i];
}
nxt[lste]=tail[i];
lst[tail[i]]=lste;
}
}
void clear(){
for(int i=1;i<=tot;i++){
lst[i]=nxt[i]=pos[i]=0;
}
for(int i=0;i<61;i++){
head[i]=0;
for(int j=1;j<=n;j++) id[j][i]=0;
tail[i]=0;
sum[i]=0;
}
for(int i=1;i<=n;i++) tim[i]=0;
tot=0;
}
void delet(int u,int k){
if(lst[id[u][k]]==0) return ;
dlst[u][k]=lst[id[u][k]];
dnxt[u][k]=nxt[id[u][k]];
nxt[dlst[u][k]]=dnxt[u][k];
lst[dnxt[u][k]]=dlst[u][k];
}
void insback(int u,int k){
nxt[lst[tail[k]]]=id[u][k];
lst[id[u][k]]=lst[tail[k]];
lst[tail[k]]=id[u][k];
nxt[id[u][k]]=tail[k];
}
void revoke(int u,int k){
int x=lst[id[u][k]],y=nxt[id[u][k]];
nxt[x]=y;
lst[y]=x;
lst[id[u][k]]=dlst[u][k],nxt[id[u][k]]=dnxt[u][k];
if(dlst[u][k]==0) return ;
nxt[lst[id[u][k]]]=id[u][k];
lst[nxt[id[u][k]]]=id[u][k];
dlst[u][k]=dnxt[u][k]=0;
}
vector< pair<int,int> > vec;
int Delet(int u,int k){
int res=(1ll<<k)-keep(u,k);
vec.push_back(make_pair(u,res));
if(res==(1ll<<k)) return res;
A[u]=a[u];
tim[u]=k;
for(int i=k-1;i>=0;i--){
if((1ll<<i)&a[u]) a[u]-=(1ll<<i),sum[i]--;
delet(u,i);
insback(u,i);
}
return res;
}
void Revoke(int u,int k){
vec.pop_back();
if(k!=tim[u]) return ;
a[u]=A[u];
A[u]=0;
tim[u]=-1;
for(int i=k-1;i>=0;i--){
if((1ll<<i)&a[u]) sum[i]++;
revoke(u,i);
}
return ;
}
int solve(int k,int cst,int spec){
if(k<0) return cst;
if(sum[k]%2==0){
int c0=n-sum[k];
if(spec==k){
if(c0<2) return inf;
int x=pos[nxt[head[k]]];
int y=pos[nxt[nxt[head[k]]]];
int res=solve(k-1,cst+Delet(x,k)+Delet(y,k),spec);
Revoke(y,k);
Revoke(x,k);
return res;
}else return solve(k-1,cst,spec);
}else{
int c0=n-sum[k];
if(c0==0) return inf;
if(spec==k) return inf;
else{
if(k>spec) return inf;
int x=pos[nxt[head[k]]];
int res=solve(k-1,cst+Delet(x,k),spec);
Revoke(x,k);
return res;
}
}
return inf;
}
vector< vector< pair<int,int> > > sol;
int now;
unordered_map<int,bool> bx;
bool dfs(int k,int cst,int spec){
if(k<0){
if(cst==ans){
now++;
sol.push_back(vec);
return true;
}
return false;
}
if(sum[k]%2==0){
int c0=n-sum[k];
if(spec==k){
if(c0<2) return false;
int x=pos[nxt[head[k]]];
int y=pos[nxt[nxt[head[k]]]];
bool res=dfs(k-1,cst+Delet(x,k)+Delet(y,k),spec);
Revoke(y,k);
Revoke(x,k);
if(res==false) return false;
if(now==m) return true;
unordered_map<int,bool> vis;
queue< pair<int,int> > q;
q.push(make_pair(x,y));
vis[min(x,y)*(n+1)+max(x,y)]=1;
while(q.size()>0){
int u=q.front().first,v=q.front().second;
q.pop();
if(nxt[id[u][k]]!=tail[k]){
int nu=pos[nxt[id[u][k]]];
if(vis[min(nu,v)*(n+1)+max(nu,v)]==0&&nu!=v){
vis[min(nu,v)*(n+1)+max(nu,v)]=1;
if(dfs(k-1,cst+Delet(nu,k)+Delet(v,k),spec)==true){
q.push(make_pair(nu,v));
}
Revoke(v,k);
Revoke(nu,k);
if(now==m){
swap(vis,bx);
bx.clear();
return true;
}
}
}
if(nxt[id[v][k]]!=tail[k]){
int nv=pos[nxt[id[v][k]]];
if(vis[min(u,nv)*(n+1)+max(u,nv)]==0&&u!=nv){
vis[min(u,nv)*(n+1)+max(u,nv)]=1;
if(dfs(k-1,cst+Delet(u,k)+Delet(nv,k),spec)==true){
q.push(make_pair(u,nv));
}
Revoke(nv,k);
Revoke(u,k);
if(now==m){
swap(vis,bx);
bx.clear();
return true;
}
}
}
}
swap(vis,bx);
bx.clear();
return true;
}else return dfs(k-1,cst,spec);
}else{
int c0=n-sum[k];
if(c0==0) return false;
if(spec==k) return false;
else{
if(k>spec) return false;
int x=pos[nxt[head[k]]];
bool res=dfs(k-1,cst+Delet(x,k),spec);
Revoke(x,k);
if(res==false) return false;
else{
if(now==m) return true;
int u=nxt[id[x][k]];
while(u!=tail[k]){
int y=pos[u];
bool res=dfs(k-1,cst+Delet(y,k),spec);
Revoke(y,k);
if(res==false||now==m) break;
u=nxt[u];
}
}
return true;
}
}
return false;
}
void work(){
ans=inf;
now=0;
cin>>n>>m;
sol.clear();
for(int i=1;i<=n;i++) cin>>a[i];
init();
vector<int> answer;
answer.resize(62);
for(int i=0;i<62;i++){
answer[i]=solve(60,0,i),ans=min(ans,answer[i]);
}
cout<<ans<<"\n";
for(int i=0;i<62;i++){
if(answer[i]==ans){
dfs(60,0,i);
}
}
cout<<now<<"\n";
for(vector< pair<int,int> > now:sol){
map<int,int> mp;
for(pair<int,int> add:now) mp[add.first]+=add.second;
cout<<mp.size()<<"\n";
for(pair<int,int> chifan:mp) cout<<chifan.first<<' ';
cout<<"\n";
for(pair<int,int> chifan:mp) cout<<chifan.second<<' ';
cout<<"\n";
}
clear();
}
signed main(){
//freopen("nim.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int c,t;
cin>>c>>t;
while(t--) work();
return 0;
}
/*
0 1
5 2000
0 6 4 7 12
*/
/*
3 5
5 2000
0 12 14 13 4
5 2000
0 14 5 5 11
5 2000
0 12 3 0 1
5 2000
0 8 5 9 11
5 2000
0 8 7 1 2
*/
/*
0 1
5 2000
0 12 3 0 1
*/