L1-7 拼接梯子
等比数列求前n项和公式 (公比为2,首项也为2),如果
是可能凑出来的(就是个二进制啊。。),反之一定表示不出来,同时,因为没有 权为1的梯子,所以奇数也是一定表示不出来的。对那些可以表示的数,找出它二进制为1的位置。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll k,n;cin>>k>>n;
if((1ll<<(k+1))-2<n || n&1) cout<<"No";
else{
cout<<"Yes"<<endl;
ll q=0;
for(ll i=0;i<63;i++){
if(n>>i&1) q=i;
}
cout<<(1ll<<q);
}
return 0;
} L1-8 幻想乡炼金学
模拟题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define dd(x) cout << #x << " = " << x << " "
#define de(x) cout << #x << " = " << x << endl
const ll mod = 1e9 + 7;
const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
ll gcd(ll a,ll b){return b ? gcd(b,a % b) : a;}
string s,ss,sss;
int main()
{
getline(cin,s);
for(int i = 0;i < s.size();++i){
if(s[i] != ' '){
ss += s[i];
}
}
string tmp;
int cnt = 0;
for(int i = 0;i < ss.size();++i){
if(ss[i] <= 'Z' && ss[i] >= 'A' && tmp.size()){
sss += tmp;
tmp = "";
tmp += ss[i];
}
else if(ss[i] == '('){
sss += tmp;
tmp = "";
while(ss[++i] != ')')
tmp += ss[i];
i++;
cnt = 0;
while(ss[i] != '}'){
i++;
if(ss[i] <= '9' && ss[i] >= '0'){
cnt = cnt * 10 + ss[i] - '0';
}
}
string res = "";
for(int j = 0;j < tmp.size();++j){
if(tmp[j] >= 'A' && tmp[j] <= 'Z'){
res += tmp[j];j++;
while(j < tmp.size() && tmp[j] < 'A' || tmp[j] > 'Z'){
res += tmp[j];
++j;
}
j--;
}
for(int k = 0;k < cnt;++k)
sss += res;
res = "";
}
tmp = "";
}
else if(ss[i] == '{'){
cnt = 0;
while(ss[i] != '}'){
i++;
if(ss[i] <= '9' && ss[i] >= '0'){
cnt = cnt * 10 + ss[i] - '0';
}
}
for(int j = 0;j < cnt;++j)
sss += tmp;
tmp = "";
}
else{
tmp += ss[i];
}
}
sss += tmp;
cout << sss << endl;
return 0;
} L2-1 特殊的沉重球
dfs暴力搜,注意剪枝(也就是记得按体重降序排个序)
#include<bits/stdc++.h>
using namespace std;
int n,w;
int a[25],b[25];
int ans;
void dfs(int x,int num){
if(num>=ans) return ;
if(x>n) {
ans=min(ans,num);return ;
}
for(int i=1;i<=num;i++){
if(a[x]+b[i]<=w){
b[i]+=a[x],dfs(x+1,num),b[i]-=a[x];
}
}
b[num+1]+=a[x];
dfs(x+1,num+1);
b[num+1]-=a[x];
}
int main(){
cin>>n>>w;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n,greater<int>());
ans=n;
dfs(1,0);
cout<<ans;
return 0;
} L2-2 又见火车入栈
因为存在查询前y项记录用STL的stack肯定是不行的,只能手写一个栈,先记录进出栈的信息,然后用离线算法,对没次询问按处理信息的数量升序排序。接着模拟进出栈就可以了。
#include<bits/stdc++.h>
using namespace std;
struct node{
int l,r;
int id;
}a[1<<20];
int ans[1<<20];
int vis[1<<20];
int sta[1<<20],tot=1;
bool cmp(node x,node y){
return x.l<y.l;
}
char s[15];
int main(){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s);
if(s[0]=='i') vis[i]=1;
}
int q;scanf("%d",&q);
for(int i=1;i<=q;i++){
int x,y;scanf("%d%d",&x,&y);
a[i]={x,y,i};
}
sort(a+1,a+1+q,cmp);
int k=0,num=1;
for(int i=1;i<=q;i++){
while(a[i].l!=k){
if(vis[++k]) sta[tot++]=num++;
else tot--;
}
ans[a[i].id]=sta[a[i].r];
}
for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
return 0;
} L2-3 新旷野地带
n行m列,枚举k,n行、m列分别选出k个,有 ,然后组成k阶方阵,因为每行每列只能选一个,所以有
种方案,总方案就是
*
。预处理阶乘,然后根据逆元来求组合数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[1<<21];
const ll mod=1e9+7;
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
int main(){
int n,m,k;cin>>n>>m>>k;
f[0]=1;
for(int i=1;i<=1000000;i++) f[i]=f[i-1]*i%mod;
ll ans=0;
k=min(k,min(n,m));
for(int i=1;i<=k;i++){
ans+=(f[n]*qpow(f[n-i]*f[i]%mod,mod-2))%mod*(f[m]*qpow(f[m-i]*f[i]%mod,mod-2)%mod)%mod*f[i]%mod;
ans%=mod;
}
cout<<ans;
return 0;
} L2-4 缘之空
LCA的板子题。
统计每个点的入度,入度为0的点就是根。两者是直系血缘关系说明有一个人是另一个人的祖先,两者的距离是 。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int head[N], nex[N<<1], to[N<<1], edge[N<<1], tot;
int n, m, s, f[N][30], h[N];
int TT;
int len[N];
void add(int x, int y, int z) {
to[tot] = y;
edge[tot] = z;
nex[tot] = head[x];
head[x] = tot++;
}
void dfs(int x, int fa) {
h[x] = h[fa] + 1;
f[x][0] = fa;
for (int i = 1; i <= TT; i++) f[x][i] = f[f[x][i - 1]][i - 1];
for (int i = head[x]; ~i; i = nex[i]) {
if(to[i] != fa) {
len[to[i]] = len[x] + edge[i];
dfs(to[i], x);
}
}
}
int LCA(int x, int y) {
if(h[x] > h[y]) swap(x, y);
for (int i = TT; i >= 0; i--)
if(h[f[y][i]] >= h[x]) y = f[y][i];
if(x == y) return x;
for (int i = TT; i >= 0; i--)
if(f[y][i] != f[x][i])
y = f[y][i], x = f[x][i];
return f[x][0];
}
int d[N];
int main()
{
int n, q; scanf("%d%d", &n, &q);
memset(head, -1, sizeof(head));
memset(len, 0, sizeof(len));
for (int i = 1, u, v; i < n; i++) {
scanf("%d %d", &u, &v);
add(u, v, 1); add(v, u, 1);
d[v]++;
}
int root = 0;
for (int i = 1; i <= n; i++) {
if(d[i] == 0) {
root = i;
break;
}
}
TT = int(log(n) / log(2)) + 1;
dfs(root, 0);
while (q--) {
int a, b;
scanf("%d%d", &a, &b);
int lca = LCA(a, b);
int ans = len[a] + len[b] - 2 * len[LCA(a, b)];
if(lca == a || lca == b) printf("NO\n");
else {
if(ans <= 4) printf("NO\n");
else printf("YES\n");
}
printf("%d\n", ans);
}
} 
京公网安备 11010502036488号