题目链接
取连续一段改为ACTG的最小代价
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
char s[100], c[] = "ACTG";
int dis(char a, char b)
{
a = a - 'A', b = b - 'A';
return min((a - b + 26) % 26, (b - a + 26) % 26);
}
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
int n;
cin >> n >> s;
int ans = INF;
for (int i = 0; i < n - 3; ++i)
{
int cnt = 0;
for (int j = 0; j < 4; ++j)
cnt += dis(s[i + j], c[j]);
ans = min(ans, cnt);
}
cout << ans << endl;
return 0;
}
矩阵每行选一个数字异或和不为0
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 510;
int g[N][N];
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
int n, m, x = 0;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
scanf("%d", &g[i][j]);
x ^= g[i][1];
}
if (x)
{
cout << "TAK" << endl;
for (int i = 1; i <= n; ++i)
cout << "1 ";
cout << endl, exit(0);
}
for (int i = 1; i <= n; ++i)
for (int j = 2; j <= m; ++j)
{
x ^= g[i][j - 1] ^ g[i][j];
if (x)
{
cout << "TAK" << endl;
for (int k = 1; k < i; ++k)
cout << "1 ";
cout << j << " ";
for (int k = i + 1; k <= n; ++k)
cout << "1 ";
cout << endl, exit(0);
}
}
cout << "NIE" << endl;
return 0;
}
给定一个序列1/2 4/3 5 7 9/6 8 10。。奇数偶数交替且长度增加一倍 问第l到r项的和
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
ll calc(ll x) //logn计算1~x项和
{
ll res = 0;
ll v[2] = { 2, 1 }, w = 1; //奇偶当前数值 项数
for (int i = 1; x; i = (i + 1) % 2, w *= 2)
{
res = (res + (v[i] + v[i] + (min(x, w) - 1) * 2LL) % MOD * (min(x, w) % MOD) % MOD * 500000004LL) % MOD; //等差数列求和 除法逆元注意炸ll
v[i] = (v[i] + w * 2LL) % MOD;
x -= min(x, w);
}
return res;
}
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
ll l, r;
cin >> l >> r;
cout << (calc(r) - calc(l - 1) + MOD) % MOD << endl;
return 0;
}
每个人有两个参数a和b 这个人的不满意度为他前面人数量a+后面人数量b 问整个队列最小不满意度
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e5 + 10;
struct node
{
ll a, b, i;
bool operator < (const node &o) const
{
return a - b > o.a - o.b;
}
}a[N];
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
scanf("%I64d%I64d", &a[i].a, &a[i].b), a[i].i = i;
sort(a + 1, a + n + 1);
ll ans = 0;
for (int i = 1; i <= n; ++i)
ans += a[i].a * (i - 1) + a[i].b * (n - i);
cout << ans << endl;
return 0;
}
给n个数字 位置相邻的两个数字之间有一条连线 f(l,r)表示只保留数值范围[l,r]节点的强连通分量数 函数f(1<=l<=r<=n)所有取值的和
计算每个点产生贡献的区间[l, r],如当前点值为a[i]则1<=l<=a[i]<=r<=n,但是如果左侧的点存在l和r的取值范围就会有些限制。
调整lr后,l和r的取值范围相乘就是当前点的贡献。
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e5 + 10;
ll a[N];
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
scanf("%I64d", &a[i]);
ll ans = 0;
for (int i = 1; i <= n; ++i)
{
ll l = a[i], r = n - a[i] + 1;
if (a[i - 1] <= a[i])
l = min(l, a[i] - a[i - 1]);
else
r = min(r, a[i - 1] - a[i]);
ans += l * r;
}
cout << ans << endl;
return 0;
}
一个01串等概率随机选取两个不同的位置进行交换 k次操作后问串为非递减序列的概率
参考大佬博客
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 110;
int C[N][N];
int a[N];
//ll f[N][N]; //f[i][j]表示i次操作j个0不在应该在的位置上
ll qpow(ll a, ll n, ll m)
{
ll res = 1;
while (n)
{
if (n & 1)
res = res * a % m;
a = a * a % m;
n >>= 1;
}
return res;
}
struct Matrix
{
ll m[N][N];
static const int N = 50; //阶数
Matrix(int v = 0)
{
memset(m, 0, sizeof(m));
if (v)
for (int i = 0; i < N; i++)
m[i][i] = v;
}
Matrix operator * (const Matrix &b)
{
Matrix t;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < N; k++)
t.m[i][j] = (t.m[i][j] + m[i][k] * b.m[k][j]) % MOD;
return t;
}
friend Matrix operator ^ (Matrix a, int n)
{
Matrix t(1);
while (n)
{
if (n & 1)
t = t * a;
a = a * a;
n >>= 1;
}
return t;
}
}tran, x; //x[0][i]表示当前状态有i个0/1不在应该在的位置上
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
C[0][0] = 1;
for (int i = 1; i < N; i++)
{
C[i][0] = 1;
for (int j = 1; j < N; j++)
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
}
int n, k, z = 0; //0个数
cin >> n >> k;
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]), z += !a[i];
int p = 0; //位置不对的个数 位置不对的1=位置不对的0
for (int i = 1; i <= z; ++i)
p += a[i];
/*
f[0][p] = 1;
int m = min(z, n - z), den = qpow(C[n][2], MOD - 2, MOD); //den总情况
for (int i = 0; i < k; ++i) //操作
for (int j = 0; j <= m; ++j) //不对的数量不会超过某个的数量
{
if (j) //交换后位置不对数量-1
f[i + 1][j - 1] = (f[i + 1][j - 1] + f[i][j] * j * j * den) % MOD; //0不对*1不对
if (j < m) //数量+1
f[i + 1][j + 1] = (f[i + 1][j + 1] + f[i][j] * (z - j) * (n - z - j) * den) % MOD; //0对*1对
f[i + 1][j] = (f[i + 1][j] + f[i][j] * (C[z][2] + C[n - z][2] + (z - j) * j + (n - z - j) * j) * den) % MOD;
}
cout << f[k][0] << endl;
*/
x.m[0][p] = 1; //初始状态100%
ll m = min(z, n - z), den = qpow(C[n][2], MOD - 2, MOD); //den总情况
for (int i = 0; i <= m; ++i) //不对的数量 不会超过某个的数量
{
int j;
if (i) //由i-1增加1个转移来
{
j = i - 1; //上个状态
tran.m[i - 1][i] = (z - j) * (n - z - j) * den % MOD; //0对*1对
}
tran.m[i][i] = (C[z][2] + C[n - z][2] + (z - i) * i + (n - z - i) * i) * den % MOD; //0/1交换 同侧01/10交换
if (i < m) //由i+1减少1个转移来
{
j = i + 1;
tran.m[i + 1][i] = j * j * den % MOD; //0不对*1不对
}
}
x = x * (tran ^ k);
cout << x.m[0][0] << endl; //输出全对情况
return 0;
}