可以粗略的看作每个数的概率都是1/2
这种取模方法需要注意 : ll te = (mod + 1) / 2; 1ll * (n - m) * te % mod;
int t;
cin >> t;
ll te = (mod + 1) / 2;
while(t--){
ll n, m;
cin >> n >> m;
cout << 1ll * (n - m) * te % mod << endl;
}
或者更好理解的:
ll qpow(ll a, ll b) {
int ans = 1;
a = (a % p + p) % p;
for (; b; b >>= 1) {
if (b & 1) ans = (a * ans) % p;
a = (a * a) % p;
}
return ans;
}
int main() {
ll mm = qpow(2, p - 2);
int t;
cin >> t;
while(t--){
ll n, m;
cin >> n >> m;
cout << (n - m) * mm % p << endl;
}
return 0;
}
博弈论
总结:
关键在于构造出0
int t;
cin >> t;
while (t--){
int n;
cin >> n;
for (int i = 0; i <= n; ++i){
cin >> a[i];
}
for (int i = n; i > 0; i--){
a[i - 1] += a[i] / 2;
}
if (a[0])
cout << "Alice" << endl;
else
cout << "Bob" << endl;
}
dij写到一半发现不对…
总结:
二进制枚举选择删去哪些墙
int n, m, k;
int xs, ys, xt, yt;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
bool g[35][35];
bool vis[35][35];
struct node
{
int x1, y1, x2, y2;
}wall[35];
int lowbit(int x){
return x & (-x);
}
void add(int k){
if(wall[k].x1 > wall[k].x2)
swap(wall[k].x1, wall[k].x2);
if(wall[k].y1 > wall[k].y2)
swap(wall[k].y1, wall[k].y2);
for (int i = wall[k].x1; i <= wall[k].x2; ++i){
for (int j = wall[k].y1; j <= wall[k].y2; ++j){
g[i][j] = true;
}
}
}
void del(int k){
if(wall[k].x1 > wall[k].x2)
swap(wall[k].x1, wall[k].x2);
if(wall[k].y1 > wall[k].y2)
swap(wall[k].y1, wall[k].y2);
for (int i = wall[k].x1; i <= wall[k].x2; ++i){
for (int j = wall[k].y1; j <= wall[k].y2; ++j){
g[i][j] = false;
}
}
}
bool bfs(){
queue<PII> q;
q.push({xs, ys});
re(vis);
vis[xs][ys] = true;
while(!q.empty()){
int x = q.front().first, y = q.front().second;
q.pop();
if(x == xt && y == yt)
return true;
for (int i = 0; i < 4; ++i){
int xx = x + dx[i], yy = y + dy[i];
if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis[xx][yy] && !g[xx][yy]){
q.push({xx, yy});
vis[xx][yy] = true;
}
}
}
return false;
}
int main()
{
int t;
cin >> t;
while (t--){
cin >> n >> m >> k;
n *= 2, m *= 2;
cin >> xs >> ys >> xt >> yt;
xs = xs * 2 + 1, ys = ys * 2 + 1, xt = xt * 2 + 1, yt = yt * 2 + 1;
for (int i = 0; i <= n; ++i){
for (int j = 0; j <= m; ++j){
g[i][j] = false;
}
}
for (int i = 0; i < k; ++i){
int x1, x2, y1, y2;
cin >> x1 >> y1 >> x2 >> y2;
wall[i] = {x1 * 2, y1 * 2, x2 * 2, y2 * 2};
}
int ans = 0;
for (int i = 0; i < (1 << k); ++i){
int cnt = 0;
for (int j = i; j; j -= lowbit(j))
++cnt;
if(cnt <= ans)
continue;
for (int j = 0; j < k; ++j){
if(i >> j & 1)
add(j);
}
if(bfs())
ans = cnt;
for (int j = 0; j < k; ++j){
if(i >> j & 1)
del(j);
}
}
cout << k - ans << endl;
}
return 0;
}
总结:
(点击跳转至原链接)
bitset<1030>f[2][1030];//f[i][j]前i个物品得到异或值位j的所有的体积状态 不要开太大了,会超时
int main() {
IOS;
int t;
scanf("%d", &t);
while(t--){
int n, m;
scanf("%d %d", &n, &m);
for (int i = 0; i < 1024; ++i)
f[0][i].reset();
f[0][0].set(0);
for (int i = 1; i <= n; ++i){
int v, w;
scanf("%d %d", &v, &w);
for (int j = 0; j < 1024; ++j){
f[i & 1][j] = f[(i & 1) ^ 1][j] | (f[(i & 1) ^ 1][j ^ w] << v);//左移v == 减v
//相当于滚动数组
/*
bitset f[N],g[N];
f[0][0] = 1;
for(int j=0;j<=1023;j++) g[j]=f[j];赋值上一维
for(int j=1023;j>=0;j--)
{
f[j]|=g[j^w]<
}
}
bool flag = true;
for (int i = 1023; i >= 0; --i){
if(f[n & 1][i][m]) {
printf("%d\n", i);
flag = false;
break;
}
}
if(flag)
printf("-1\n");
}
return 0;
}