标签:name break struct 一个 double printf mes pac min
? 一串序列,求所有连续区间数字和的期望。
? 先求出前缀和\(s[i] \ (\sum_{k=1}^{i} a[k])\),做如下操作
长度为1的区间的和加起来得到 \(s[n]\)
长度为2的区间的和加起来得到 \(s[n]+s[n-1]-s[1]\)
长度为3的区间的和加起来得到 \(s[n]+s[n-1]+s[n-2]-s[1]-s[2]\)
? 规律就很明显了,再做一次前缀和的前缀和。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 2e5 + 7;
const int mod = 1e9 + 7;
ll T, n;
ll s[maxn];
ll qpow(ll a, ll b) {
ll ans = 1;
while(b) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
ll m(ll a) {
return (a % mod + mod ) % mod;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
cin >> T;
while(T--) {
cin >> n;
for(int i = 1; i <= n; i++) cin >> s[i];
for(int i = 1; i <= n; i++) s[i] = (s[i] + s[i-1])%mod;
for(int i = 1; i <= n; i++) s[i] = (s[i] + s[i-1])%mod;
ll ans = 0, temp = 0;
for(int i = 1; i <= n; i++) {
ans += m(m(s[n]-s[n-i]-s[i-1]) * qpow(i, mod - 2) % mod);
ans %= mod;
}
ans = ans * qpow(n*(n+1)/2%mod, mod -2) % mod;
cout << m(ans) << endl;
}
return 0;
}
? 给一个四则运算公式,判断能满足这个公式的最小进制。
? 直接模拟,需要注意除法不是整数除法,所以判断的时候使用\(b*c==a\)。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 7;
const int mod = 1e9 + 7;
string s;
map<char, int> mp;
void init() {
mp[‘0‘] = 0; mp[‘1‘] = 1; mp[‘2‘] = 2; mp[‘3‘] = 3;
mp[‘4‘] = 4; mp[‘5‘] = 5; mp[‘6‘] = 6; mp[‘7‘] = 7;
mp[‘8‘] = 8; mp[‘9‘] = 9; mp[‘A‘] = 10; mp[‘B‘] = 11;
mp[‘C‘] = 12; mp[‘D‘] = 13; mp[‘E‘] = 14; mp[‘F‘] = 15;
}
ll convert(int base, string num) {
ll ans = 0, p = 1;
for(int i = num.size() - 1; i >= 0; i--) {
ans += mp[num[i]] * p;
p = p * base;
}
return ans;
}
bool judge(int base, string a, char opt, string b, string c) {
ll na = convert(base, a);
ll nb = convert(base, b);
ll nc = convert(base, c);
if(opt == ‘+‘) return na + nb == nc;
if(opt == ‘-‘) return na - nb == nc;
if(opt == ‘*‘) return na * nb == nc;
return nc * nb == na;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
init();
while(cin >> s) {
string num[3];
num[0] = num[1] = num[2] = "";
int now = 0, ans = -1; char opt;
for(int i = 0; i < s.size(); i++) {
if(mp.count(s[i])) num[now] += s[i];
else if(s[i] != ‘=‘) {
opt = s[i];
now++;
}
else now++;
}
int base = 2;
for(int _ = 0; _ < 3; _++) {
for(char ch: num[_]) {
if(ch <= ‘9‘) base = max(base, ch - ‘0‘ + 1);
else base = max(base, ch - ‘A‘ + 11);
}
}
for(int i = base; i <= 16; i++) {
if(judge(i, num[0], opt, num[1], num[2])) {
ans = i;
break;
}
}
cout << ans << endl;
}
return 0;
}
? 一个无向连通图,求所有的1点到0点的最短距离的路径和。
? 考虑到第\(i\)条边的长度为\(2^i\),而\(\sum_{i=0}^{n-1}2^i \ = \ 2^n-1\)。所以需要尽量使用前面的边,按输入顺序求最小生成树即可。然后按照一个方向遍历最小生成树,记录每一个点顺着这个方向能到达的1类点和0类点。
? 最终答案就是按照遍历顺序求每条边的贡献
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 7;
const int mod = 1e9 + 7;
int T, n, m, cnt[2], ans = 0;
int a[maxn], fa[maxn], nxt[maxn][2];
vector<pair<int, int>> G[maxn];
int find(int x) {
return x == fa[x]?fa[x]:(fa[x] = find(fa[x]));
}
int qpow(int a, int b) {
int ans = 1;
while(b) {
if(b & 1) ans = (ll)ans * a % mod;
a = (ll)a * a % mod;
b >>= 1;
}
return ans;
}
void dfs(int u, int from) {
nxt[u][a[u]]++;
for(auto p: G[u]) {
if(p.first==from) continue;
dfs(p.first, u);
nxt[u][0] += nxt[p.first][0];
nxt[u][1] += nxt[p.first][1];
}
// 遍历每一个点,与点直接相连的边的贡献为nxt[u][0]*(cnt1-nxt[u][1])*w + nxt[u][1]*(cnt0-nxt[u][0])*w;
for(auto p: G[u]) {
if(p.first == from) continue;
ans = ((ll)ans + (ll)nxt[p.first][0] * (cnt[1] - nxt[p.first][1]) % mod * p.second) % mod;
ans = ((ll)ans + (ll)nxt[p.first][1] * (cnt[0] - nxt[p.first][0]) % mod * p.second) % mod;
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
cin >> T;
while(T--) {
cin >> n >> m;
cnt[0] = cnt[1] = ans = 0;
for(int i = 1; i <= n; i++) {
cin >> a[i];
cnt[a[i]]++;
nxt[i][0] = nxt[i][1] = 0;
fa[i] = i;
G[i].clear();
}
// 最小生成树
for(int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v;
w = qpow(2, i);
int x = find(u), y = find(v);
if(x == y) continue;
fa[x] = y;
G[u].push_back({v, w});
G[v].push_back({u, w});
}
dfs(1, -1);
cout << ans << endl;
}
return 0;
}
? 如下定义\(y=\overline{c_{1} c_{2} \cdots c_{n}}\),\(f(y)=\sum_{i=1}^{n} c_{i}, \text { if } \underbrace{f(f(\cdots f(y) \cdots))}_{\infty}\) 。
? 命题:对于b进制下任意一个数字是否都有 \(f(y)\)能被\(x\)整除,则\(y\)能被\(x\)整除,否者不能被\(x\)整除。
? 问命题是否成立
? 考虑将一个数分解为\(num=a_nb^n+a_{n-1}b^{n-1}+...+a_2b^2+a_1b^1+a_0\)。
? 要使各位数之和\(sum\%x == num\%x\),也就是\(b^n\%x=1,\quad b^{n-1}\%x=1, \quad..., \quad b^1\%x=1\),即\(b\%x=1\)。
? 因此对于\(b\)进制下,当\(x=b-1\)时命题成立。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 7;
const int mod = 1e9 + 7;
int T;
ll n, x;
int a[maxn];
int main() {
ios::sync_with_stdio(false); cin.tie(0);
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
cin >> T;
while(T--) {
cin >> n >> x;
n--;
if(n % x == 0) cout << "T\n";
else cout << "F\n";
}
return 0;
}
标签:name break struct 一个 double printf mes pac min
原文地址:https://www.cnblogs.com/leiyuanze/p/13469526.html