8.【2024初三年前集训测试3】

qwq

2024初三年前集训测试3

T1夕景昨日

90pts

  • 不好想,一直做到最后了,然后发现过不了样例,发现读假题了 qwq😓😓😓

题解

  • 只要发现规律,就很好做了。当 n>20 (也有人说是 n>24 时),我们直接输出 Yes 即可 (莫名想到某星战n20 时暴搜完全可过。
  • 为什么?因为当 n20 时,所有状态和为 220=1048576 ,但是值域却是 1 ~ 500000 。(或者说当 n=25 时,总状态有 225=16777216 种状态。假设值域开满,那么就有 5×105×50=25000000 ),因此在此时状态一定会冲突,于是输出 Yes 即可。

代码

暴搜打的不好了,应该用函数但没想到怎么打。

#include<bits/stdc++.h>
#define int long long
#define N (10000010)
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<25;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<25,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48&&c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char end){pit(x);*o++=end;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;
inline signed min(signed x,signed y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline long long min(long long x,long long y){return y&((y-x)>>63)|x&(~(y-x)>>63);}
inline signed max(signed x,signed y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline long long max(long long x,long long y){return x&((y-x)>>63)|y&(~(y-x)>>63);}
inline void swap(signed &x,signed &y){x^=y^=x^=y;}
int n,m;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
int a[100010];
map<signed,signed>s;
signed main()
{
init_set();
cin>>n;
if(n>20)puts("Yes"),exit(0);
for(int i(1);i<=n;++i)cin>>a[i];
if(n<=20)
{
if(n==1)puts("No"),exit(0);
if(n==2)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
if(s.find(a[1]*i+a[2]*j)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j];
if(n==3)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
for(int k(-1);k<=1;k+=2)
if(s.find(a[1]*i+a[2]*j+a[3]*k)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j+a[3]*k];
if(n==4)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
for(int k(-1);k<=1;k+=2)
for(int i4(-1);i4<=1;i4+=2)
if(s.find(a[1]*i+a[2]*j+a[3]*k+a[4]*i4)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j+a[3]*k+a[4]*i4];
if(n==5)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
for(int k(-1);k<=1;k+=2)
for(int i4(-1);i4<=1;i4+=2)
for(int i5(-1);i5<=1;i5+=2)
if(s.find(a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5];
if(n==6)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
for(int k(-1);k<=1;k+=2)
for(int i4(-1);i4<=1;i4+=2)
for(int i5(-1);i5<=1;i5+=2)
for(int i6(-1);i6<=1;i6+=2)
if(s.find(a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6];
if(n==7)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
for(int k(-1);k<=1;k+=2)
for(int i4(-1);i4<=1;i4+=2)
for(int i5(-1);i5<=1;i5+=2)
for(int i6(-1);i6<=1;i6+=2)
for(int i7(-1);i7<=1;i7+=2)
if(s.find(a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7];
if(n==8)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
for(int k(-1);k<=1;k+=2)
for(int i4(-1);i4<=1;i4+=2)
for(int i5(-1);i5<=1;i5+=2)
for(int i6(-1);i6<=1;i6+=2)
for(int i7(-1);i7<=1;i7+=2)
for(int i8(-1);i8<=1;i8+=2)
if(s.find(a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7+a[8]*i8)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7+a[8]*i8];
if(n==9)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
for(int k(-1);k<=1;k+=2)
for(int i4(-1);i4<=1;i4+=2)
for(int i5(-1);i5<=1;i5+=2)
for(int i6(-1);i6<=1;i6+=2)
for(int i7(-1);i7<=1;i7+=2)
for(int i8(-1);i8<=1;i8+=2)
for(int i9(-1);i9<=1;i9+=2)
if(s.find(a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7+a[8]*i8+a[9]*i9)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7+a[8]*i8+a[9]*i9];
if(n==10)
for(int i(-1);i<=1;i+=2)
for(int j(-1);j<=1;j+=2)
for(int k(-1);k<=1;k+=2)
for(int i4(-1);i4<=1;i4+=2)
for(int i5(-1);i5<=1;i5+=2)
for(int i6(-1);i6<=1;i6+=2)
for(int i7(-1);i7<=1;i7+=2)
for(int i8(-1);i8<=1;i8+=2)
for(int i9(-1);i9<=1;i9+=2)
for(int i10(-1);i10<=1;i10+=2)
{
//cout<<i<<' '<<j<<' '<<k<<' '<<i4<<' '<<i5<<' '<<i6<<' '<<i7<<' '<<i8<<' '<<i9<<' '<<i10<<'\n';
//cout<<a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7+a[8]*i8+a[9]*i9+a[10]*i10<<'\n';
if(s.find(a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7+a[8]*i8+a[9]*i9+a[10]*i10)!=s.end())
puts("Yes"),exit(0);
else ++s[a[1]*i+a[2]*j+a[3]*k+a[4]*i4+a[5]*i5+a[6]*i6+a[7]*i7+a[8]*i8+a[9]*i9+a[10]*i10];
}
puts("No"),exit(0);return 0;
}
flush();
return 0;
}

T2透明答案

(100pts)(70pts)30pts

  • 7 分钟首 A 但是瞎搞,所以觉得不是正解,手搓 13 的数据,于是大力模 2 。。。。。。然后30分。 😔😟😩
  • 30pts 输出 Bob 70pts 输出 Ayano 😂👉😂👉😂👉
  • 还有, OI 赛制滚出 OI 😠😠😠😡😡😡😭😭😭

题解

  • 由于最优解可能会有不同拿取方式,(其实是蒟蒻模拟不出来qwq)因此不再模拟。
  • n=1 时, Ayano 赢, n=2 时, Bob 赢 , n=3 时, Ayano 赢, n=4 时, Ayano 赢, n=5 时, Bob 赢, n=6 时, Ayano 赢。

代码

#include<bits/stdc++.h>
#define int long long
#define N (1)
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<25;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<25,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char end){pit(x);*o++=end;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;
inline signed min(signed x,signed y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline long long min(long long x,long long y){return y&((y-x)>>63)|x&(~(y-x)>>63);}
inline signed max(signed x,signed y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline long long max(long long x,long long y){return x&((y-x)>>63)|y&(~(y-x)>>63);}
inline void swap(signed &x,signed &y){x^=y^=x^=y;}
int n,m;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
int x,y,xx,yy,a,b,d,sum,ans;
signed main()
{
init_set();
n=read();
if(n%3==1)puts("Ayano");
else if(n%3==2)puts("Bob");
else puts("Ayano");
flush();
return 0;
}

T3界外科学

100pts

  • 不会打,大力打了个暴搜,加了个剪枝,结果首 A 😨😱 。赛后被 hack 了。并且发现数据太水了!!! 😅 。输出和就 AC 了。

题解

  • 正解:meet in middle01Trie ,复杂度 O(2n2log(n))
  • 这里不打正解,正解可以去别处看 qwq 大佬的博客

代码

  • 难绷,剪枝把整棵树都剪了,导致随机超大数据下 n=100000 有时能卡进 1000ms
  • 但是通过超多对拍显示(大约 50 万组),当 m 极其小时,会被 T 飞,原因就是剪枝需要更新答案,而 m 十分小导致更新答案也十分困难,因此会被卡掉。最坏复杂度 O(2n) 😥😥😥
  • 但是当价值超大时,比如是 m220 倍时,可能会 T 飞。因此:

暴力虽好,可不要贪多哦。。。

  • 当然十分好的复杂度可以达到 O(1) (当第一遍剪枝就减掉整棵搜索树(比如所有满足度小于等于 0 )时)。

  • 解决方案:当 m<=1e4 时,完全可以 DP 解决,而 m>1e4 时, 就用 dfs 暴搜。

  • 又一解决方案:将价格转为二进制,并将超大的价格删去(价格改为 1 ,价值改为 0 (其实改价值不重要,之后用 sort 排序排到最后即可))。并且只当价格大于 m 且二进制最高位为 1 ,(其实大于 m 的只有一个的任意一位均可),之后可以再卡掉一些 hack 数据。

  • 再一解决方案,双向搜索(折半搜索( meet in middle )),可惜我不会打,只能打出最慢 O(2n) 的折半搜索(这真的折半了吗?)。

  • 最终复杂度 O(???)

  • DFS _ v1

#include<bits/stdc++.h>
#define int long long
#define sort stable_sort
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<25;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<25,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char end){pit(x);*o++=end;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;
inline signed min(signed x,signed y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline long long min(long long x,long long y){return y&((y-x)>>63)|x&(~(y-x)>>63);}
inline signed max(signed x,signed y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline long long max(long long x,long long y){return x&((y-x)>>63)|y&(~(y-x)>>63);}
inline void swap(signed &x,signed &y){x^=y^=x^=y;}
int n,m;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
int ans,cnt,Sum[1010];
struct aa{int x,y;}e[1010];
bool cmp(aa a,aa b){return a.y<b.y;}
void dfs(int x,int val,int sum)
{
//++cnt;//计数器
if(x>n){if(val<=m)ans=max(ans,sum);return;}
if(sum+Sum[n]-Sum[x-1]<=ans)return;//剪枝
dfs(x+1,val,sum);
if(sum+Sum[n]-Sum[x-1]<=ans)return;//意义不大,但有用
dfs(x+1,val^e[x].x,sum+e[x].y);
if(val<=m)ans=max(ans,sum);
return;
}
signed main()
{
init_set();
n=read();m=read();
for(int i(1);i<=n;++i)e[i].x=read();
for(int i(1);i<=n;++i)e[i].y=read();
sort(e+1,e+1+n,cmp);
for(int i(1);i<=n;++i)Sum[i]=Sum[i-1]+((e[i].y>0)?e[i].y:0);
dfs(1,0,0);
//write(cnt,' ');
write(ans,' ');
flush();
return 0;
}
  • DFS _ hacker _ v1
#include<bits/stdc++.h>
#define int long long
#define N (10000010)
const int MAXN=1ll*2147483647;
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<25;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<25,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char end){pit(x);*o++=end;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;
inline signed min(signed x,signed y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline long long min(long long x,long long y){return y&((y-x)>>63)|x&(~(y-x)>>63);}
inline signed max(signed x,signed y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline long long max(long long x,long long y){return x&((y-x)>>63)|y&(~(y-x)>>63);}
inline void swap(signed &x,signed &y){x^=y^=x^=y;}
int n,m,ans;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
signed main()
{
init_set();
srand(std::chrono::system_clock::now().time_since_epoch().count());
n=36;m=10000;
cout<<n<<' '<<m<<'\n';//write(n,' ');write(m,'\n');
for(int i(1);i<=n;++i)
if(i<=15)write(((1<<(i+14))),' ');
else write(1,' ');
*IO::o++='\n';
for(int i(1);i<=n;++i)
if(i<=15)write((10000000),' ');
else write(1,' ');
flush();
return 0;
}

直接卡到原形 2n

  • DFS _ v2
  • 原理是将超级大的价格大于 m 的最高位并且在所有数中某位二进制唯一的数删除(价值赋值为 1 ,价格赋值为 0 )。之后排序扔到最后面。
  • 将一些重复的价格异或为 0 (如果价值大于 0 ),并将价值累加。
  • 因此可以卡掉 DFS _ hacker _ v1 ,只需要 8191 次运算,等于 2131
#include<bits/stdc++.h>
#define int long long
#define sort stable_sort
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<26;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<26,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char end){pit(x);*o++=end;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;
inline signed min(signed x,signed y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline long long min(long long x,long long y){return y&((y-x)>>63)|x&(~(y-x)>>63);}
inline signed max(signed x,signed y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline long long max(long long x,long long y){return x&((y-x)>>63)|y&(~(y-x)>>63);}
inline void swap(signed &x,signed &y){x^=y^=x^=y;}
int n,m;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
int ans,cnt,Sum[3000000],TLE[50],rer;
int TP[300][50],bit[100],TOP(1<<29);
struct aa{int x,y;}e[3000000];
bool cmp(aa a,aa b){return a.y<b.y;}
bool xcmp(aa a,aa b){return a.x>b.x;}
void dfs(int x,int val,int sum)
{
//++cnt;
if(x>n){if(val<=m)ans=max(ans,sum);return;}
if(sum+Sum[n]-Sum[x-1]<=ans)return;
dfs(x+1,val^e[x].x,sum+e[x].y);
if(sum+Sum[n]-Sum[x-1]<=ans)return;
dfs(x+1,val,sum);
if(val<=m)ans=max(ans,sum);
return;
}
void bits(int x)
{
for(int i(1),pos(1);i<TOP;i<<=1,++pos)
bit[pos]=(i&x)?1:0;
}
void bitt(int x,int p)
{
for(int i(1),pos(1);i<TOP;i<<=1,++pos)
TP[p][pos]+=(i&x)?1:0,TLE[pos]+=(i&x)?1:0;
}
signed main()
{
init_set();
n=read();m=read();
bits(m);
for(int i(1);i<=n;++i)e[i].x=read(),bitt(e[i].x,i);
for(int i(1);i<=n;++i)e[i].y=read();
for(int i(1);i<=n;++i)
{
for(int j(1);j<=29;++j)
if(TLE[j]==1&&(1<<j)>m&&TP[i][j])
{++rer;e[i].x=-1,e[i].y=0;break;}
}
for(int i(1);i<=n;++i)
for(int j(i+1);j<=n;++j)
if(e[i].x==e[j].x&&e[i].x!=-1&&e[i].y>=0&&e[j].y>=0)
{
e[i].x=0,e[j].x=-1,e[i].y+=e[j].y,e[j].y=0;
++rer;
}
sort(e+1,e+1+n,xcmp);
n-=rer;
sort(e+1,e+1+n,cmp);
for(int i(1);i<=n;++i)Sum[i]=Sum[i-1]+((e[i].y>0)?e[i].y:0);
dfs(1,0,0);
//write(cnt,' ');
write(ans,' ');
flush();
return 0;
}
  • DFS _ hacker _ v2
#include<bits/stdc++.h>
#define int long long
#define N (10000010)
const int MAXN=1ll*2147483647;
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<25;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<25,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char end){pit(x);*o++=end;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;
inline signed min(signed x,signed y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline long long min(long long x,long long y){return y&((y-x)>>63)|x&(~(y-x)>>63);}
inline signed max(signed x,signed y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline long long max(long long x,long long y){return x&((y-x)>>63)|y&(~(y-x)>>63);}
inline void swap(signed &x,signed &y){x^=y^=x^=y;}
int n,m,ans;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
signed main()
{
init_set();
srand(std::chrono::system_clock::now().time_since_epoch().count());
n=36;m=10000;
cout<<n<<' '<<m<<'\n';//write(n,' ');write(m,'\n');
for(int i(1);i<=n;++i)
if(i<=15)write(((1<<(i+14))+(1<<(i+13))),' ');
else write(1,' ');
*IO::o++='\n';
for(int i(1);i<=n;++i)
if(i<=15)write((10000000),' ');
else write(1,' ');
flush();
return 0;
}
  • 这一版 DFS _ hacker 的效果并没有像预想中的那么好, DFS _ v2 仍然可以在 0.2s 内运行。

  • 但是将 m 改成 10i 改为 i<=27 输出 ((1<<(i+2))+(1<<(i+1))) 就有很大效果了。需要运算 4294967295 次,等于 2321 ,已经卡死了 qwq

  • DFS _ v3

  • 这是最后一版 DFS ,用上了蒟蒻已知的大多数优化,双向搜索。但是效果并不好,因为在最后计算答案时会退化,并且可能会出错。所以这版烂尾了 qwq

#include<bits/stdc++.h>
#define int long long
#define sort stable_sort
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<26;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<26,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char end){pit(x);*o++=end;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;
inline signed min(signed x,signed y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline long long min(long long x,long long y){return y&((y-x)>>63)|x&(~(y-x)>>63);}
inline signed max(signed x,signed y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline long long max(long long x,long long y){return x&((y-x)>>63)|y&(~(y-x)>>63);}
inline void swap(signed &x,signed &y){x^=y^=x^=y;}
int n,m;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
int ans,cnt,Sum[300000],TLE[50],ans2,rer;
int TP[300][50],bit[100],TOP(1<<29);
int ansqwq;
struct aa{int x,y;}e[300000];
vector<aa>qwq,pmp;
bool cmp(aa a,aa b){return a.y<b.y;}
bool gcmp(aa a,aa b){return a.y>b.y;}
bool lcmp(aa a,aa b){return a.x>b.x;}
void dfs(int x,int val,int sum)
{
//++cnt;
if(x>(n>>1)){qwq.push_back({val,sum});if(val<=m)ans=max(ans,sum);return;}
if(sum+Sum[n]-Sum[x-1]<=ans)return;//剪枝
dfs(x+1,val,sum);
if(sum+Sum[n]-Sum[x-1]<=ans)return;//意义不大,但有用
dfs(x+1,val^e[x].x,sum+e[x].y);
return;
}
void dfs2(int x,int val,int sum)
{
//++cnt;
if(x>n){pmp.push_back({val,sum});if(val<=m)ans2=max(ans2,sum);return;}
if(sum+Sum[n]-Sum[x-1]<=ans2)return;
dfs2(x+1,val,sum);
if(sum+Sum[n]-Sum[x-1]<=ans2)return;
dfs2(x+1,val^e[x].x,sum+e[x].y);
return;
}
void dfss()
{
dfs(1,0,0);
dfs2((n>>1)+1,0,0);
}
void bits(int x)
{
for(int i(1),pos(1);i<=TOP;i<<=1,++pos)
bit[pos]=(i&x)?1:0;
}
void bitt(int x,int p)
{
for(int i(1),pos(1);i<=TOP;i<<=1,++pos)
TP[p][pos]+=(i&x)?1:0,TLE[pos]+=(i&x)?1:0;
}
signed main()
{
init_set();
n=read();m=read();
bits(m);
for(int i(1);i<=n;++i)e[i].x=read(),bitt(e[i].x,i);
for(int i(1);i<=n;++i)e[i].y=read();
for(int i(1);i<=n;++i)
for(int j(i+1);j<=n;++j)
if(e[i].x==e[j].x&&e[i].x!=-1&&e[i].y>=0&&e[j].y>=0)
{
e[i].x=0,e[j].x=-1,e[i].y+=e[j].y,e[j].y=0;
++rer;
}
if(rer)sort(e+1,e+1+n,lcmp),n-=rer;
sort(e+1,e+1+n,cmp);
for(int i(1);i<=n;++i)Sum[i]=Sum[i-1]+((e[i].y>0)?e[i].y:0);
dfss();
sort(qwq.begin(),qwq.end(),gcmp);
sort(pmp.begin(),pmp.end(),gcmp);
for(aa i:qwq)
{
for(aa j:pmp)
{
if((i.x^j.x)<=m)
{
ansqwq=max(ansqwq,i.y+j.y);
}
if(ansqwq>=((i.y)*(j.y)))break;
}
if(ansqwq>=((i.y)*(pmp.front().y)))break;
}
//write(cnt,' ');
write(ansqwq,'\n');
flush();
return 0;
}
  • 刚才的 hack 跑了 30 秒,加上这句可以少跑 15 秒。
  • 也许双向搜索本身并没有多占时间,但是后面最劣 O(cnt2) 的复杂度还是望而生畏。。。
  • 双向搜索一共搜索 196606 次。
  • 正确率大约 85% 。原因是 dfs2 中的剪枝是错误的,不可以直接这样剪枝。但是改掉又十分慢。。。
for(int i(29);i;--i)
{
if(bit[i])break;
for(int j(1);j<=n;++j)
{
if(TLE[i]==1&&TP[j][i])
{
++rer;e[i].x=-1,e[i].y=0;
for(int k(1);k<=29;++k)
if(TP[i][k])TP[i][k]=0,--TLE[k];
break;
}
}
}
  • 剪枝应该是这个。
void dfs2(int x,int val,int sum)
{
//++cnt;
if(x>n){pmp.push_back({val,sum});if(val<=m)ans2=max(ans2,sum);return;}
if(sum+Sum[n]-Sum[x-1]+Sum[(n>>1)]<=ans2)return;
dfs2(x+1,val,sum);
if(sum+Sum[n]-Sum[x-1]+Sum[(n>>1)]<=ans2)return;
dfs2(x+1,val^e[x].x,sum+e[x].y);
return;
}
  • 最后发现 DFS _ 2 才是最好的。 😥😥😥

  • 附简单 hack 数据生成器。

#include<bits/stdc++.h>
#define int long long
#define N (10000010)
const int MAXN=1ll*2147483647;
using namespace std;
namespace IO
{
#define ll long long
const int MAX=1<<25;
char buf[MAX],*p1=buf,*p2=buf;
char obuf[MAX],*o=obuf;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<25,stdin),p1==p2)?EOF:*p1++)
//template<typename T>
//inline T read()
inline int read()
{
int x=0;bool f=1;
char c=gc();
for(;c<48||c>57;c=gc())if(c=='-')f=0;
for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48);
return f?x:~x+1;
}
void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';}
void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);}
void write(ll x,char end){pit(x);*o++=end;}
void flush(){fwrite(obuf,o-obuf,1,stdout);}
#undef ll
}
using IO::read;using IO::write;using IO::flush;
inline signed min(signed x,signed y){return y&((y-x)>>31)|x&(~(y-x)>>31);}
inline long long min(long long x,long long y){return y&((y-x)>>63)|x&(~(y-x)>>63);}
inline signed max(signed x,signed y){return x&((y-x)>>31)|y&(~(y-x)>>31);}
inline long long max(long long x,long long y){return x&((y-x)>>63)|y&(~(y-x)>>63);}
inline void swap(signed &x,signed &y){x^=y^=x^=y;}
int n,m,ans;
void init_set()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","w",stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
}
signed main()
{
//init_set();
srand(std::chrono::system_clock::now().time_since_epoch().count());
n=36;m=10000;
cout<<n<<' '<<m<<'\n';//write(n,' ');write(m,'\n');
for(int i(1);i<=n;++i){
//if(i<=8)write(((1<<(i+14))),' ');
if(i<=8)cout<<rand()%2000000+2000000<<' ';//write(rand()%2000000+2000000,' ');
else cout<<rand()%10<<' ';//write(rand()%10,' ');
}
cout<<'\n';//*IO::o++='\n';
for(int i(1);i<=n;++i){
//if(i<=8)write((10000000),' ');
if(i<=8) cout<<rand()%1000000+1000000<<' ';//write(rand()%1000000+1000000,' ');
else cout<<rand()%10-3<<' ';//write(rand()%10-3,' ');
}
flush();
return 0;
}

T4回忆补时

30pts

  • 本次模拟赛唯一能够不被成为“💩”的题。但是还是“💩”(因为打不出来😓😓😓)。正解:李超线段树。
  • 其中 30pts 暴力枚举 O(n2q)
  • 60pts 维护最值和次值(本来想这么打,但是觉得打了也没什么意义,就没打😤😤😤)。

题解

  • (無)

代码

  • (無)

qwq
image

image

image

posted @   minecraft114514  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示