8.【2024初三年前集训测试3】
2024初三年前集训测试3
T1夕景昨日
- 不好想,一直做到最后了,然后发现过不了样例,发现读假题了
。
题解
- 只要发现规律,就很好做了。当
(也有人说是 时),我们直接输出 即可 (莫名想到某星战) 时暴搜完全可过。 - 为什么?因为当
为 时,所有状态和为 ,但是值域却是 ~ 。(或者说当 时,总状态有 种状态。假设值域开满,那么就有 ),因此在此时状态一定会冲突,于是输出 即可。
代码
暴搜打的不好了,应该用函数但没想到怎么打。
#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透明答案
分钟首 但是瞎搞,所以觉得不是正解,手搓 到 的数据,于是大力模 。。。。。。然后30分。 。 输出 输出- 还有,
赛制滚出
题解
- 由于最优解可能会有不同拿取方式,(
其实是蒟蒻模拟不出来qwq)因此不再模拟。 - 当
时, 赢, 时, 赢 , 时, 赢, 时, 赢, 时, 赢, 时, 赢。
代码
#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界外科学
- 不会打,大力打了个暴搜,加了个剪枝,结果首
。赛后被 了。并且发现数据太水了!!! 。输出和就 了。
题解
- 正解:
与 ,复杂度 。 - 这里不打正解,正解可以去别处看
大佬的博客
代码
- 难绷,剪枝把整棵树都剪了,导致随机超大数据下
有时能卡进 。 - 但是通过超多对拍显示(大约
万组),当 极其小时,会被 飞,原因就是剪枝需要更新答案,而 十分小导致更新答案也十分困难,因此会被卡掉。最坏复杂度 。 - 但是当价值超大时,比如是
的 倍时,可能会 飞。因此:
暴力虽好,可不要贪多哦。。。
-
当然十分好的复杂度可以达到
(当第一遍剪枝就减掉整棵搜索树(比如所有满足度小于等于 )时)。 -
解决方案:当
时,完全可以 解决,而 时, 就用 暴搜。 -
又一解决方案:将价格转为二进制,并将超大的价格删去(价格改为
,价值改为 (其实改价值不重要,之后用 排序排到最后即可))。并且只当价格大于 且二进制最高位为 ,(其实大于 的只有一个的任意一位均可),之后可以再卡掉一些 数据。 -
再一解决方案,双向搜索(折半搜索(
)),可惜我不会打,只能打出最慢 的折半搜索(这真的折半了吗?)。 -
最终复杂度
。 -
_
#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; }
_ _
#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; }
直接卡到原形
_- 原理是将超级大的价格大于
的最高位并且在所有数中某位二进制唯一的数删除(价值赋值为 ,价格赋值为 )。之后排序扔到最后面。 - 将一些重复的价格异或为
(如果价值大于 ),并将价值累加。 - 因此可以卡掉
_ _ ,只需要 次运算,等于 。
#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; }
_ _
#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; }
-
这一版
_ 的效果并没有像预想中的那么好, _ 仍然可以在 内运行。 -
但是将
改成 或 , 改为 输出 就有很大效果了。需要运算 次,等于 ,已经卡死了 。 -
_ -
这是最后一版
,用上了蒟蒻已知的大多数优化,双向搜索。但是效果并不好,因为在最后计算答案时会退化,并且可能会出错。所以这版烂尾了 。
#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; }
- 刚才的
跑了 秒,加上这句可以少跑 秒。 - 也许双向搜索本身并没有多占时间,但是后面最劣
的复杂度还是望而生畏。。。 - 双向搜索一共搜索
次。 - 正确率大约
。原因是 中的剪枝是错误的,不可以直接这样剪枝。但是改掉又十分慢。。。
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; }
-
最后发现
_ 才是最好的。 。 -
附简单
数据生成器。
#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回忆补时
- 本次模拟赛唯一能够不被成为“
💩”的题。但是还是“💩”(因为打不出来)。正解:李超线段树。 - 其中
暴力枚举 。 维护最值和次值(本来想这么打,但是觉得打了也没什么意义,就没打 )。
题解
- (無)
代码
- (無)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探