补体记录: B D G H
B A+B
这道题虽然我的大致思路和题解差不多 也是利用b的长度来处理 但我处理枚举等能力太弱了 根本不知道可以直接暴力枚举来统计答案 结果就抛弃了这个想法 导致浪费了几小时吃土
#include<bits/stdc++.h>
using namespace std;
#define int long long
int ans = 0;
int n;
int pow1(int a, int b)
{
if (b == 0)
return 1;
int res = 1;
while (b)
{
if (b & 1)
{
res = res * a;
}
a = a * a;
b >>= 1;
}
return res;
}
signed main()
{
cin >> n;
int len = log10(n)+1;
// cout << len << endl;
for (int i = 1; i <=len; i++)
{
for (int j = 0; j <=i; j++)
{
for (int k = 0; k <= i; k++)
{
int p = pow1(2, j)*pow1(5, k);
int l = pow1(10, i-1), r = min(n, pow1(10, i) - 1);
ans += (r / p - (l - 1) / p);
}
}
}
cout << ans;
}
D:
这个构造题要是没对二进制有一定理解是写不出来的
#include<algorithm>
#include<set>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
#define int long long
const int maxn = 1e5 + 10;
void solve()
{
set<int>s;
while (s.size())
s.erase(*s.begin());
string now ;
for (int i = 0; i <= 31; i++){
cout << "+ " << i << endl;
s.insert(i);
cin >> now;
if (now == "YES")
{
string ss;
for (int j = 0; j < i; j++)
{
cout << "- " << j<<endl;
cin >> ss;
s.erase(j);
if (ss == "NO")
{
cout << "! " << i - j << endl;
cin >> ss;
return;
}
}
}
}
for (int i = 1; i <= 32; i++)
{
int x = 32 * i + 31;
cout << "+ " << x << endl;
s.insert(x);
cin >> now;
if (now == "YES")
{
string ss;
for (int j = 0; j <= 31; j++)
{
cout << "- " << j<<endl;
cin >> ss;
s.erase(j);
if (ss == "NO")
{
cout << "! " << x - j << endl;
cin >> ss;
return;
}
}
}
}
}
signed main()
{
int t;
cin >> t;
while (t--)
solve();
}
G :
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
int dp[maxn][8];//dp[i][j]代表数字i 最大位数为j的方案数
signed main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
if (i >= 1)
{
if (i == 1)
{
dp[i][1] = 1;
}
else
{
dp[i][1] += dp[i - 1][1];
dp[i][1] %= mod;
}
}
if (i >= 2)
{
if (i == 2)
{
dp[2][2] = 1;
}
else
{
dp[i][2] += dp[i - 2][1] + dp[i - 2][2];
dp[i][2] %= mod;
}
}
if (i >= 3)
{
if (i == 3)
dp[3][3] = 1;
else
{
dp[i][3] += dp[i - 3][1] + dp[i - 3][2] + dp[i - 3][3];
dp[i][3] %= mod;
}
}
if (i >= 5)
{
if (i == 5)
dp[5][5] = 1;
else
{
dp[i][5] += dp[i - 5][1] + dp[i - 5][2] + dp[i - 5][5]+dp[i-5][3];
dp[i][5] %= mod;
}
}
if (i >= 7)
{
if (i == 7)
dp[7][7] = 1;
else
{
dp[i][7] += dp[i - 7][7] + dp[i - 7][1] + dp[i - 7][2] + dp[i - 7][5]+dp[i-7][3];
dp[i][7] %= mod;
}
}
}
int ans = 1;
for (int i = 1; i <= 7; i++)
(ans += dp[n][i]) %= mod;
cout << ans;
}
H: 思路参考 :middle(洛谷)
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int maxn = 3e5 + 10;
struct node
{
int l, r;
int pref_max, pref_min, sum, suff_max, suff_min;
}tree[maxn<<2];
int a[maxn], cnt[maxn];
int b[maxn];
void pushup(int rt){
tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
tree[rt].pref_max = max(tree[rt << 1].pref_max, tree[rt << 1].sum + tree[rt << 1 | 1].pref_max);
tree[rt].suff_max = max(tree[rt << 1 | 1].suff_max, tree[rt << 1 | 1].sum + tree[rt << 1].suff_max);
tree[rt].pref_min = min(tree[rt << 1].pref_min, tree[rt << 1].sum + tree[rt << 1 | 1].pref_min);
tree[rt].suff_min = min(tree[rt << 1 | 1].suff_min, tree[rt << 1 | 1].sum + tree[rt << 1].suff_min);
}
void build(int rt, int l, int r)
{
tree[rt].l = l, tree[rt].r = r;
if (l == r)
{
tree[rt].pref_max = tree[rt].pref_min = tree[rt].suff_max = tree[rt].suff_min = tree[rt].sum = b[l];
return;
}
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
pushup(rt);
}
void modify(int rt, int l, int r, int q, int v)//单点
{
if (l == q && r == q)
{
tree[rt].pref_max = tree[rt].pref_min = tree[rt].suff_max = tree[rt].suff_min = tree[rt].sum = v;
return;
}
int mid = l + r >> 1;
if (q <= mid)
modify(rt << 1, l, mid, q, v);
else
modify(rt << 1 | 1, mid + 1, r, q, v);
pushup(rt);
}
int querysum(int rt, int l, int r, int ql, int qr)
{
if (l == ql && r == qr)
return tree[rt].sum;
int mid = l + r >> 1;
if (qr <= mid)
return querysum(rt << 1, l, mid, ql, qr);
else if (ql > mid)
return querysum(rt << 1 | 1, mid + 1, r, ql, qr);
else
{
int ret = querysum(rt << 1, l, mid, ql, mid);
ret += querysum(rt << 1|1, mid + 1, r, mid + 1, qr);
return ret;
}
}
int queryprefmax(int rt, int l, int r, int ql, int qr)
{
if (l == ql && r == qr)
return tree[rt].pref_max;
int mid = l + r >> 1;
if (qr <= mid)
{
return queryprefmax(rt << 1, l, mid, ql, qr);
}
else if (ql > mid)
return queryprefmax(rt << 1 | 1, mid + 1, r, ql, qr);
else
{
int ret = queryprefmax(rt << 1, l, mid, ql, mid);
int ret2 = querysum(rt << 1, l, mid, ql, mid) + queryprefmax(rt << 1 | 1, mid + 1, r, mid + 1, qr);
return max(ret, ret2);
}
}
int queryprefmin(int rt, int l, int r, int ql, int qr)
{
if (l == ql && r == qr)
return tree[rt].pref_min;
int mid = l + r >> 1;
if (qr <= mid)
return queryprefmin(rt << 1, l, mid, ql, qr);
else if (ql > mid)
return queryprefmin(rt << 1 | 1, mid+1, r, ql, qr);
else
{
int ret = queryprefmin(rt << 1, l, mid, ql, mid);
int ret2 = querysum(rt << 1, l, mid, ql,mid) + queryprefmin(rt << 1 | 1, mid + 1, r, mid + 1, qr);
return min(ret, ret2);
}
}
int querysuffmax(int rt, int l, int r, int ql, int qr)
{
if (l == ql && r == qr)
return tree[rt].suff_max;
int mid = l + r >> 1;
if (qr <= mid)
{
return querysuffmax(rt << 1, l, mid, ql, qr);
}
else if (ql > mid)
return querysuffmax(rt << 1 | 1, mid + 1, r, ql, qr);
else
{
int ret = querysuffmax(rt << 1|1, mid+1,r, mid+1,qr);
int ret2 = querysum(rt << 1|1, mid+1, r, mid+1, qr) + querysuffmax(rt << 1, l, mid,ql,mid);
return max(ret, ret2);
}
}
int querysuffmin(int rt, int l, int r, int ql, int qr)
{
if (l == ql && r == qr)
return tree[rt].suff_min;
int mid = l + r >> 1;
if (qr <= mid)
return querysuffmin(rt << 1, l, mid, ql, qr);
else if (ql > mid)
return querysuffmin(rt << 1 | 1, mid + 1, r, ql, qr);
else
{
int ret = querysuffmin(rt << 1|1, mid+1, r, mid+1, qr);
int ret2 = querysum(rt << 1|1, mid+1, r, mid+1, qr) + querysuffmin(rt << 1 , l, mid,ql,mid);
return min(ret, ret2);
}
}
void solve(){
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (a[i] < 1)
b[i] = -1;
else if (a[i] == 1)
b[i] == 0;
else
b[i] = 1;
cnt[a[i]] = i;
}
build(1, 1, n);
for (int i = 1; i <= n; i++)
{
//cout << i << endl;
int preemax = 0, preemin = 0;
int suffmax = 0, suffmin = 0;
if (cnt[i] != 1)//代表前面有数
{
preemax = querysuffmax(1, 1, n, 1, cnt[i]-1);
preemin =querysuffmin(1, 1, n, 1, cnt[i]-1);
//1 左边是0
if (preemin <= 0 && preemax >= 0)
{
cout << "y";
modify(1, 1, n, cnt[i], -1);
if(i!=n)
modify(1, 1, n, cnt[i + 1], 0);
continue;
}
}
if (cnt[i] != n)//代表后面有数
{
suffmax =queryprefmax(1, 1, n, cnt[i]+1, n);
suffmin =queryprefmin(1, 1, n, cnt[i]+1, n);
if (suffmax >= 0 && suffmin <= 0)
{
cout << 'y';
modify(1, 1, n, cnt[i], -1);
if(i!=n)
modify(1, 1, n, cnt[i + 1], 0);
continue;
}
}
if (cnt[i] == n)//代表后米面没有数
{
if (preemax >= 0 && preemin <= 0)//代表前面有数
{
cout << 'y';
}
else
cout << 'n';
}
else if (cnt[i] == 1)
{
if (suffmin <= 0 && suffmax >= 0)
{
cout << 'y';
}
else
cout << 'n';
}
else
{
if (preemin <= -suffmin && preemax >= -suffmax)
{
cout << 'y';
}
else
cout << "n";
}
modify(1, 1, n, cnt[i], -1);
if(i!=n)
modify(1, 1, n, cnt[i + 1], 0);
//cout << endl;
}
cout <<'\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)
solve();
}