A - WOW Factor
ans += 出现o的位置前的w数量 * o后面的w数量
// Problem: A - WOW Factor
// Contest: Virtual Judge - 22练习赛
// URL: https://vjudge.net/contest/578163#problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
#include<memory>//for unique_ptr shared_ptr
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA(x) cout << x << endl;
#define lowbit(x) x & -x
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
int n, m, k, d, T = 1, A, B;
template<typename T>void read(T &x) {
T f = 1;x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename T>void print(T x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
putchar('\n');
}
constexpr int Init(int x)
{
return x * 2;
}
int pre[maxn];//前i个位置有多少个vv
void solve()
{
auto x = make_unique<int>();
string s;
cin >> s;
int n = s.size();
s = "*" + s;
for(int i = 1;i <= n;i++)
{
pre[i] = pre[i - 1] + (s[i] == 'v' && s[i - 1] == 'v');
}
int ans = 0;
for(int i = 1;i <= n;i++)
{
if(s[i] == 'o')
ans += (pre[i - 1] * (pre[n] - pre[i]));
}
cout << ans << endl;
}
signed main() {
cin.tie(0) -> sync_with_stdio(false);
int T = 1;
//read(T);
while (T--) solve();
return 0;
}
B - Mishka and the Last Exam
贪心的想a[i] + a[n - i + 1] == b[i]
通过b数组构造a(非降序)则希望前者尽量小,后者尽量大
对于b[1]可以确定头and尾
则令a[n] = b[1] a[1] = 0
后面的构造也是将b[i]拆分赋值给a[i] and a[n - i + 1]
∵非降序则a[i]至少为a[i - 1]而a[n - i + 1]至少小于等于a[n - i + 2]
可得
又∵
很愉快的TIL
先前考虑优先满足前者
∵题目保证至少可以构造一组a,即一定有解
那么我们索性再贪一点让a[n - i + 1] 赋值为a[n - i + 2]
那么 a[i] = b[i] - a[n - i + 1];
如果此时破坏了a的规则,则我们希望a[i]尽可能小,a[n - i + 1]尽可能大
// Problem: B - Mishka and the Last Exam
// Contest: Virtual Judge - 22练习赛
// URL: https://vjudge.net/contest/578163#problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
#include<memory>//for unique_ptr shared_ptr
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA(x) cout << x << endl;
#define lowbit(x) x & -x
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
int n, m, k, d, T = 1, A, B;
template<typename T>void read(T &x) {
T f = 1;x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename T>void print(T x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
putchar('\n');
}
constexpr int Init(int x)
{
return x * 2;
}
int a[maxn];
int b[maxn];
void solve()
{
auto x = make_unique<int>();
cin >> n;
for(int i = 1;i <= n / 2;i++)cin >> b[i];
//b[i] = a[i] + a[n - i + 1];
//b[1] = a[1] + a[n]
//b[2] = a[2] + a[n - 1]
//b[3] = a[3] + a[n - 2]
a[1] = 0;
a[n] = b[1];
for(int i = 2;i <= n / 2;i++)
{
a[n - i + 1] = min(a[n - i + 2], b[i]);
a[i] = b[i] - a[n - i + 1];
if(a[i] < a[i - 1])
{
a[i] = a[i - 1];
a[n - i + 1] = b[i] - a[i];
}
}
for(int i = 1;i <= n;i++)
cout << a[i] << " ";
}
signed main() {
cin.tie(0) -> sync_with_stdio(false);
int T = 1;
//read(T);
while (T--) solve();
return 0;
}
C - Queen
∵叶子节点没有儿子节点,那么就不存在儿子节点尊重它(???题目的真理)
∴我们初始化默认每一个节点都不被子节点尊重
每轮输入其子节点编号p及c(1不尊重父节点,0反之)
其中每一个节点只存在一个父节点则显然 fa[i] = c即可
而p相对i为父节点 == > i是p的子节点
若c == 0 则p被子尊重son[p] = 0;
∵p可以有多个子节点 == >> 一次为0永久为0 && son[p]默认初始化1
则通过son[p] &= c即可
// Problem: C - Queen
// Contest: Virtual Judge - 22练习赛
// URL: https://vjudge.net/contest/578163#problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
#include<memory>//for unique_ptr shared_ptr
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA(x) cout << x << endl;
#define lowbit(x) x & -x
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
int n, m, k, d, T = 1, A, B;
template<typename T>void read(T &x) {
T f = 1;x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename T>void print(T x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
putchar('\n');
}
constexpr int Init(int x)
{
return x * 2;
}
int fa[maxn];//i 是否尊重父亲
int son[maxn];// 是否被儿子尊重
void solve()
{
auto x = make_unique<int>();
cin >> n;
memset(son, 1, sizeof son);
for(int i = 1;i <= n;i++)
{
int p, c;
cin >> p >> c;
if(-1 == p)continue;
fa[i] = c;
son[p] &= c;
}
bool is = false;
for(int i = 1;i <= n;i++)
{
if(fa[i] && son[i])
{
is = true;
cout << i << " ";
}
}
if(!is) cout << -1 << endl;
}
signed main() {
cin.tie(0) -> sync_with_stdio(false);
int T = 1;
//read(T);
while (T--) solve();
return 0;
}
D - Zero Quantity Maximization
根据公式 任意x = a[i] * d + b[i]
// Problem: D - Zero Quantity Maximization
// Contest: Virtual Judge - 22练习赛
// URL: https://vjudge.net/contest/578163#problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
#include<memory>//for unique_ptr shared_ptr
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA(x) cout << x << endl;
#define lowbit(x) x & -x
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
int n, m, k, d, T = 1, A, B;
template<typename T>void read(T &x) {
T f = 1;x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename T>void print(T x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
putchar('\n');
}
constexpr int Init(int x)
{
return x * 2;
}
int a[maxn], b[maxn];
map<long double,int>Mod;
void solve()
{
auto x = make_unique<int>();
cin >> n;
int z = 0;
// c - b[i] = a[i] * d
// 令 c = 0
// d = -b[i] / a[i] ==>> 出现最多的d的次数 + 一定为0的个数即 a[i] == b[i] == 0
for(int i = 1;i <= n;i++)cin >> a[i];
for(int i = 1;i <= n;i++)cin >> b[i];
for(int i = 1;i <= n;i++)
{
if(a[i] == 0){z += (b[i] == 0);continue;}
Mod[(long double)-b[i] / a[i]]++;
}
int ans = 0;
for(auto x : Mod)
ans = max(ans, x.second);
cout << ans + z << endl;
}
signed main() {
cin.tie(0) -> sync_with_stdio(false);
int T = 1;
//read(T);
while (T--) solve();
return 0;
}
根据题意可以知道一个情况
每次吃xi ,其余 + xi,若xi == 0则sum最终为0(x1 = 0 | 1)
那么贪心的将,希望sum最大,我们希望 + xi最大,每次吃掉的xi就为最大
统计1的个数,若1的个数为0 == >> ans = 0
else
对于1的变化一定为 1 2 4 8 ……(每次吃最大,第一次一定吃1,则最大变为2,吃2,变为4……)
num1 个 1的贡献等于 pow(2,num1) - 1
对于num0 个0 前num1个操作使得此时的0变成pow(2,num1) - 1
num0个操作后面0的贡献为(pow(2,num1) - 1) * (pow(2,num0) - 1)
ans = pow(2,num1) - 1 + (pow(2,num1) - 1) * (pow(2,num0) - 1) = (pow(2,num1) - 1) * (pow(2,num0) )
我们用线段树维护区间[l,r]中间1的个数(写完发现前缀和即可,看到区间就想线段树了%……)
// Problem: E - Banh-mi
// Contest: Virtual Judge - 22练习赛
// URL: https://vjudge.net/contest/578163#problem/E
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
#include<memory>//for unique_ptr shared_ptr
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA(x) cout << x << endl;
#define lowbit(x) x & -x
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
int n, m, k, d, T = 1, A, B;
template<typename T>void read(T &x) {
T f = 1;x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename T>void print(T x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
putchar('\n');
}
constexpr int Init(int x)
{
return x * 2;
}
string s;
struct node
{
int l, r, w;
}tr[maxn];
void pushup(int u)
{
tr[u].w = tr[u << 1].w + tr[u << 1 | 1].w;
}
int mypow(int a, int n)
{
int ans = 1;
while (n)
{
if (n & 1)
{
n -= 1;
ans = ans * a % mod;
}
else
{
n /= 2;
a = a * a % mod;
}
}
return ans;
}
void built(int u, int l, int r)
{
tr[u] = {l, r};
if(l == r)tr[u].w = (s[l] == '1');
else
{
int mid = (l + r) >> 1;
built(u << 1,l, mid);
built(u << 1 | 1,mid + 1, r);
pushup(u);
}
}
int query(int u ,int l, int r)
{
if(tr[u].l >= l && tr[u].r <= r)return tr[u].w;
int mid = (tr[u].l + tr[u].r) >> 1;
int res = 0;
if(l <= mid)res += query(u << 1, l, r);
if(r > mid)res += query(u << 1 | 1, l, r);
return res;
}
void solve()
{
auto x = make_unique<int>();
cin >> n >> m >> s;
s = "*" + s;
built(1, 1, n);
//cout << tr[1].l << " " << tr[1].r << " " << tr[1].w << endl;
while(m--)
{
int l, r;
cin >> l >> r;
int num1 = query(1, l, r);
int num0 = (r - l + 1) - num1;
if(num1 == 0)cout << 0 << endl;
else
{
int ans = (mypow(2, num1) - 1) * mypow(2, num0);
cout << ans % mod << endl;
}
}
}
signed main() {
cin.tie(0) -> sync_with_stdio(false);
int T = 1;
//read(T);
while (T--) solve();
return 0;
}
F - The Number Of Good Substrings
首先暴力先行
枚举1到n的数字
将数字转换为二进制串
if(t.size() > n)break;后续不可能出现 == 的情况
else k = i - t.size();//前补0
只需要查找s中间t出现的次数累加即可
// Problem: F - The Number Of Good Substrings
// Contest: Virtual Judge - 22练习赛
// URL: https://vjudge.net/contest/578163#problem/F
// Memory Limit: 256 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
#include<memory>//for unique_ptr shared_ptr
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA(x) cout << x << endl;
#define lowbit(x) x & -x
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
int n, m, k, d, T = 1, A, B;
template<typename T>void read(T &x) {
T f = 1;x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename T>void print(T x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
putchar('\n');
}
constexpr int Init(int x)
{
return x * 2;
}
int check(const std::string& s, const std::string& t) {
int count = 0;
size_t pos = s.find(t);
while (pos != std::string::npos) {
count++;
pos = s.find(t, pos + 1);
}
return count;
}
void solve()
{
auto x = make_unique<int>();
string s;
cin >> s;
int n = s.size();
int ans = 0;
for(int i = 1;i <= n; i++)
{
string t = bitset<32>(i).to_string();
t = t.substr(t.find('1'));
if(t.size() > i)break;
if(t.size() < i)
{
int k = i - t.size();
for(int j = 1;j <= k;j++)
t = "0" + t;
}
//cout << i << " " << t << endl;
ans += check(s, t);
}
cout << ans << endl;
}
signed main() {
cin.tie(0) -> sync_with_stdio(false);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}
然后 很愉快的TIL
不难想 二进制下出现0(前往后)数字num的变化 == num << 1 = num * 2
若出现1(再末尾)num += 1
从前往后枚举(0 -> n)
∵前置0对num没有任何作用
∴我们直接先跳到距离i最近的1的位置(用a[i]保存)
和先前讲解的一样若次数 num == j(尾) - i(头) + 1满足答案条件ans++
若 > break;
// Problem: F - The Number Of Good Substrings
// Contest: Virtual Judge - 22练习赛
// URL: https://vjudge.net/contest/578163#problem/F
// Memory Limit: 256 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<sstream>//切割strtream头文件
#include<climits>//INT_MAX文件
#include <utility>
#include<memory>//for unique_ptr shared_ptr
using i64 = int64_t;
using namespace std;
#define int i64
#define endl '\n'
#define AC return 0;
#define WA(x) cout << x << endl;
#define lowbit(x) x & -x
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
int n, m, k, d, T = 1, A, B;
template<typename T>void read(T &x) {
T f = 1;x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename T>void print(T x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
putchar('\n');
}
constexpr int Init(int x)
{
return x * 2;
}
int a[maxn];//记录最近的一个1
void solve()
{
string s;
cin >> s;
int n = s.size(), pre = n;
int ans = 0;
for(int i = n - 1;i >= 0;i--)
{
if(s[i] == '1')
pre = i;
a[i] = pre;
}
for(int i = 0; i < n;i++)
{
int num = 0;
for(int j = a[i];j < n;j++)
{
num *= 2;
if(s[j] == '1')num++;
if(num == j - i + 1)ans++;`
if(num > n) break;
}
}
cout << ans << endl;
}
signed main() {
cin.tie(0) -> sync_with_stdio(false);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}