暑假集训csp提高模拟24

赛时 rank43,T1 100,T2 31,T3 0,T4 9

T2 由于学校机子的O2跑的还没有本地的O1快(太快啦!!!),挂了40pts

T4 暴力没有取模和特判,挂了5pts

与和

[ABC238D] AND and SUM

签到题

由于x&y=a,所以有x+y=s2a

考虑二进制下的加法,如果有一个sth满足a2+sth=s,那么sth&a一定为0。

sa2的二进制表示出来,与a按位与,如果不为0,那么就为No,反之为Yes。

注意特判s2a<0的情况,此时答案一定为No。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#ifdef LOCAL
FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
// FILE *ErrFile=errfile("err.err");
#else
FILE *Infile = stdin,*OutFile = stdout;
//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
inline void solve(){
int T;cin>>T;
while(T--){
ll a,s;
cin>>a>>s;
ll c = s-a*2;
if(c < 0){cout<<"No\n";continue;}
bool flag = c&a;
cout<<(flag?"No\n":"Yes\n");
}
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
solve();
}

函数

[ABC366F] Maximum Composition

赛时将输入random_shuffle了

然后赛后试了试,卡了卡时,学校oj可以拿97,AT上WA一个

有模拟退火+卡时过的,正解是推柿子。

如果f1(f2(x))>f2(f1(x)),那么有A1A2x+A1B2+B1>A2A1x+A2B1+B2

再推一下,就有B2(A11)>B1(A21),然后还有B2A21>B1A11

按照BA1降序排列,写个O(nk)的背包就过了。

时间复杂度O(nk+nlogn)

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#ifdef LOCAL
FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
// FILE *ErrFile=errfile("err.err");
#else
FILE *Infile = stdin,*OutFile = stdout;
//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 2e5 + 10;
struct node{int a,b,id;}a[N];
int n,k;
ll f[20];
inline void solve(){
cin>>n>>k;
for(int i = 1;i <= n; ++i){
cin>>a[i].a>>a[i].b;
a[i].id = i;
}
ll res = 0;
sort(a+1,a+1+n,[](node x,node y){return 1.0*x.b/(x.a-1) > 1.0*y.b/(y.a-1);});
for(int j = 0;j <= k; ++j)f[j] = 1;
for(int i = 1;i <= n; ++i){
for(int j = k;j >= 1; --j){
f[j] = max(f[j],a[i].a*f[j-1]+a[i].b);
}
}
cout<<f[k];
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
solve();
}

袋鼠

[CEOI2016] kangaroo

预设型dp

考虑转化题意,就是一个1n的排列,满足s为第一位,t为最后一位,对于第2n-1位,两边的数同时大于或小于它的方案数。

fi,j表示已经将前i个数,分成了j段的方案数。

对于当前枚举到的数i摆放的位置进行分讨。

  1. 新开一段 :

因为后面加的数一定比i大,所以以后插在i两边的数一定合法,插入前有j1段,有j个空可以放。

但如果i>s则头不能放,如果i>t则尾不能放。

所以有

fi,j=(j[i>s][i>t])×fi1,j1

  1. 接在某一段的头或者尾

不合法

  1. 将两段连起来

上一步有j1段,有j个空可以插。

所以有

fi,j=j×fi1,j+1

  1. 对于s,t的特殊处理

只可能插在最前面或最后面,要么是自己新开了一段,要么接在某一段头部或尾部

所以有

fi,j=fi1,j1+fi1,j

目标为fn,1,初始状态为f1,1=1

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#ifdef LOCAL
FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
// FILE *ErrFile=errfile("err.err");
#else
FILE *Infile = stdin,*OutFile = stdout;
//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 2e3 + 10,mod = 1e9 + 7;
int n,s,t,f[N][N];
inline void solve(){
cin>>n>>s>>t;
f[1][1] = 1;
for(int i = 2;i <= n; ++i){
for(int j = 1;j <= i; ++j){
if(s != i && t != i)
f[i][j] = (1ll*j*f[i-1][j+1]%mod + 1ll*(j-(i>s)-(i>t))*f[i-1][j-1]%mod)%mod;
else f[i][j] = (f[i-1][j-1] + f[i-1][j])%mod;
}
}
cout<<f[n][1];
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
solve();
}

最短路

题目不难,放个*3000不算难吧

The Classic Problem

不会写,以后有能力做vjudge题单时再写

挂个标签 : 可持久化线段树,hash,最短路

posted @   CuFeO4  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示