[CSP-S模拟测试110]题解
也许是最后一篇了。
A.最大或
不错的签到题。
对于二进制位来说,高位的一个1比低位的所有1的贡献总和还要大。
显然,
首先
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include<cstdio> #include<cstring> #include<iostream> #include<cmath> using namespace std; typedef long long ll; int T; ll l,r; void work() { scanf ( "%lld%lld" ,&l,&r); ll res=0; bool ok=0; for ( int i=62;i>=0;i--) { int now=(r>>i)&1LL,nowl=(l>>i)&1LL; if (now!=nowl)ok=1; //cout<<i<<' '<<now<<' '<<nowl<<' '<<ok<<endl; if (!now) if ((res|(1LL<<i))<=r&&ok)res|=1LL<<i; } printf ( "%lld\n" ,r|res); } int main() { freopen ( "maxor.in" , "r" ,stdin); freopen ( "maxor.out" , "w" ,stdout); scanf ( "%d" ,&T); while (T--)work(); return 0; } |
B.答题
题意可以转化为:求用所给的
然后就是裸的折半搜索了。分别搜出前一半和后一半的子集和,然后二分答案。
之后考虑如何求 从两组数里各取一个数,且令取出的两数和
先把两组数排序,然后枚举第一组选到哪个,第二组维护一个倒着扫的单调指针即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,a[45],n1,n2,sz1,sz2; double p; ll kth; vector< int >s1,s2; void dfs( int x, int tot, int op) { if (!op&&x>n1) { s1.push_back(tot); return ; } if (op&&x>n) { s2.push_back(tot); return ; } dfs(x+1,tot,op); dfs(x+1,tot+a[x],op); } bool check( int val) { ll res=0; int j=sz2; for ( int i=0;i<sz1;i++) { res+=sz2-j; while (j>0&&s2[j-1]+s1[i]>=val)j--,res++; } return res>=kth; } #define F int main() { #ifdef F freopen ( "answer.in" , "r" ,stdin); freopen ( "answer.out" , "w" ,stdout); #endif scanf ( "%d%lf" ,&n,&p); for ( int i=1;i<=n;i++) scanf ( "%d" ,&a[i]); kth=(1LL<<n)- ceil (1.0*(1LL<<n)*p)+1; n1=n/2; dfs(1,0,0);dfs(n1+1,0,1); sz1=s1.size();sz2=s2.size(); sort(s1.begin(),s1.end()); sort(s2.begin(),s2.end()); int l=0,r=1e9,ans; while (l<=r) { int mid=l+r>>1; if (check(mid))ans=mid,l=mid+1; else r=mid-1; } cout<<ans<<endl; return 0; } |
C.联合权值·改
其实正解挺神的……但是它w范围这么小 不用白不用啊。
直接开桶维护每个联合权值的个数,然后利用bitset去除三元环的情况即可。
我没脸
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include<cstdio> #include<iostream> #include<cstring> #include<bitset> using namespace std; #define pa pair<int,int> #define re register inline int read() { int x=0,f=1; char ch= getchar (); while (! isdigit (ch)){ if (ch== '-' )f=-1;ch= getchar ();} while ( isdigit (ch))x=x*10+ch- '0' ,ch= getchar (); return x*f; } typedef long long ll; const int N=3e4+5; int n,m,t; int to[N<<1],head[N],nxt[N<<1],tot,ansm; pa p[N<<1]; bitset<N> s[N]; ll w[N],anss,bu[N>>1],cnt[N>>1]; inline void add(re int x,re int y) { to[++tot]=y; nxt[tot]=head[x]; head[x]=tot; } inline void print() { if (t!=2) printf ( "%d\n" ,ansm); else puts ( "0" ); if (t!=1) printf ( "%lld\n" ,anss); else puts ( "0" ); } #define F int main() { #ifdef F freopen ( "link.in" , "r" ,stdin); freopen ( "link.out" , "w" ,stdout); #endif n=read();m=read();t=read(); for (re int i=1;i<=m;i++) { int x=read(),y=read(); p[i]=make_pair(x,y); add(x,y);add(y,x);s[x][y]=1;s[y][x]=1; } for (re int i=1;i<=n;i++) w[i]=read(); for (re int x=1;x<=n;x++) { memset (bu,0, sizeof (bu)); for (re int i=head[x];i;i=nxt[i]) { int y=to[i]; for ( int k=1;k<=100;k++) cnt[w[y]*k]+=bu[k]; bu[w[y]]++; } } for ( int i=1;i<=m;i++) { int now=(s[p[i].first]&s[p[i].second]).count(); //cout<<i<<' '<<now<<endl; cnt[w[p[i].first]*w[p[i].second]]-=now; } for ( int i=1;i<=10000;i++) anss+=1LL*i*cnt[i],ansm=max(ansm,cnt[i]?i:0); anss*=2; print(); return 0; } |
兴许青竹早凋,碧梧已僵,人事本难防。
本文作者:Rorschach_XR
本文链接:https://www.cnblogs.com/Rorschach-XR/p/11838305.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步