2019牛客多校 Round3
2024-09-02 12:05:23
Solved:3
Rank:105
治哥出题了 我感动哭了
A Graph Game (分块)
题意:1e5个点 2e5条边 s(x)表示与x点直接相邻的点集合
有两种操作 1种将按输入顺序的边第l条到第r条边翻转 连接->切断 切断->链接
还有一种询问 s(x)与s(y)是否相等
题解:题解说 可以给每个点随机一个值 然后s(x)可以用与x直接相邻的点xor起来 (还有这种操作???
然后我们把边分块 翻转操作就是xor操作 每个点之间边的状态是一样的 所以可以共用
而且对一条边的修改 影响的只有两个点的信息 所以对块两边的边暴力修改他所影响的点
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5; int n, m, blo;
int bl[MAXN << 1];
int sum[MAXN][505];
int now[MAXN];
int val[MAXN];
int u[MAXN << 1];
int v[MAXN << 1];
int vis[505]; void update(int l, int r) {
for(int i = l; i <= min(r, bl[l] * blo); i++) {
now[u[i]] ^= val[v[i]];
now[v[i]] ^= val[u[i]];
} if(bl[l] != bl[r]) {
for(int i = (bl[r] - 1) * blo + 1; i <= r; i++) {
now[u[i]] ^= val[v[i]];
now[v[i]] ^= val[u[i]];
}
}
for(int i = bl[l] + 1; i < bl[r]; i++) vis[i] ^= 1;
} int main() {
srand(time(NULL));
for(int i = 1; i <= 100000; i++) val[i] = rand() + 1; int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
blo = sqrt(m);
for(int i = 1; i <= m; i++) bl[i] = (i - 1) / blo + 1;
for(int i = 1; i <= n; i++) now[i] = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= bl[m]; j++) sum[i][j] = 0;
for(int i = 1; i <= bl[m]; i++) vis[i] = 1; for(int i = 1; i <= m; i++) {
scanf("%d%d", &u[i], &v[i]);
sum[u[i]][bl[i]] ^= val[v[i]];
sum[v[i]][bl[i]] ^= val[u[i]];
} int qu; scanf("%d", &qu);
while(qu--) {
int opt, x, y;
scanf("%d%d%d", &opt, &x, &y);
if(opt == 1) update(x, y);
else if(opt == 2) {
int ans1 = now[x], ans2 = now[y];
for(int i = 1; i <= bl[m]; i++) {
if(vis[i]) {
ans1 ^= sum[x][i];
ans2 ^= sum[y][i];
}
}
if(ans1 == ans2) printf("1");
else printf("0");
}
}
puts("");
}
return 0;
}
A Graph Game
F Planting Trees
题意:500x500的矩阵 求一个最大的子矩阵 使得区间最大减最小<=M
题解:枚举纵坐标的区间 对于每一个区间 从第一行开始 单调尺取搞一搞
#include <bits/stdc++.h>
using namespace std; int a[505][505];
int zd[505];
int zx[505]; int qd[505];
int qx[505]; int main() {
int T;
scanf("%d", &T);
while(T--) {
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
} int ans = 1;
for(int j = 1; j <= n; j++) {
for(int k = 1; k <= n; k++) {
zx[k] = 1e5 + 5;
zd[k] = 0;
}
for(int k = j; k <= n; k++) {
for(int i = 1; i <= n; i++) {
zd[i] = max(zd[i], a[i][k]);
zx[i] = min(zx[i], a[i][k]);
} int lx = 1, rx = 0;
int ld = 1, rd = 0; int nowl = 1;
for(int i = 1; i <= n; i++) {
while(lx <= rx && zx[qx[rx]] >= zx[i]) rx--;
qx[++rx] = i;
while(ld <= rd && zd[qd[rd]] <= zd[i]) rd--;
qd[++rd] = i; while(nowl <= i && zd[qd[ld]] - zx[qx[lx]] > m) {
nowl++;
while(lx <= rx && qx[lx] < nowl) lx++;
while(ld <= rd && qd[ld] < nowl) ld++;
}
if(nowl <= i && zd[qd[ld]] - zx[qx[lx]] <= m) {
ans = max(ans, (k - j + 1) * (i - nowl + 1));
}
}
}
}
printf("%d\n", ans);
}
return 0;
}
F Planting Trees
G Removing Stones
题意:n堆石子 每次可以选择两堆不同的各拿走一个 如果能拿完 就表示获胜
如果石子的和为奇数 则将最少的一堆石子数-1
问有多少对区间 能获胜
题解:显然 题目等于 计算 区间max * 2 <= 区间和的个数
考虑反问题 计算max * 2 > 区间和
然后直接暴力枚举每个点作为最大值 往前搞搞 往后搞搞
巧妙的是这样的时间复杂度其实并不高 要让这样暴力枚举的时间复杂度退化到n方的数据 显然是ai >= ai+1 * 2
举个例子长度为5的数组 16 8 4 2 1 能让暴力枚举的复杂度退化到n方 但是ai < 1e9
均摊一下每个数的平均枚举到log
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[300005];
ll pre[300005]; int main() {
int T;
scanf("%d", &T);
while(T--) {
ll n;
scanf("%lld", &n);
for(int i = 1; i <= n; i++) scanf("%lld", &a[i]); ll ans = 0;
for(int i = 1; i <= n; i++) {
int cnt = 0;
pre[0] = 0;
for(int j = i + 1; j <= n; j++) {
pre[++cnt] = a[j];
pre[cnt] += pre[cnt - 1];
if(pre[cnt] >= a[i]) {
cnt--;
break;
}
} ans += cnt;
ll sum = 0;
for(int j = i - 1; j >= 1; j--) {
sum += a[j];
if(sum >= a[i]) break; ans++;
int l = 0, r = cnt;
int mid = l + r >> 1;
while(l + 1 < r) {
mid = l + r >> 1;
if(sum + pre[mid] < a[i]) l = mid;
else r = mid;
}
if(sum + pre[r] < a[i]) ans += r;
else ans += l;
}
} ans = n * (n - 1) / 2 - ans;
printf("%lld\n", ans);
} return 0;
}
G Removing Stones
最新文章
- 关于mysql 查询内容不区分大小问题
- java生成二维码(需导入第三方ZXing.jar包)
- ios7技巧:你需要掌握的19个iOS7使用技巧
- 一篇文章一张思维导图看懂Android学习最佳路线
- BZOJ 1724 切割木板
- MySQL Server-id的作用
- 查看SGA和PGA使用率
- IntelliJ IDEA14如何配置tomcat
- FlashbackQuery:SCN与timestamp示例
- Python成长之路第二篇(1)_数据类型内置函数用法
- poj 1050 To the Max_dp求最大子矩阵和
- Android - Mac系统Android程序位置
- js分析 汽_车_之_家 js生成css伪元素 hs_kw44_configUS::before
- Python 能做什么?
- [lightoj P1306] Solutions to an Equation
- WordPress版微信小程序2.1.8版发布
- lua -- 清理数组
- 多线程消息监听容器配置[ 消费者spring-kafka配置文件]
- C#让应用程序只运行一个实例的几种方法
- angular 4 路由变化的时候实时监测刷新组件