鱼C论坛

 找回密码
 立即注册
查看: 365|回复: 23

[已解决]萌新妹子求帅哥带,代码清新可爱,不知道哪里错了,求调~(悬15鱼币 10 贡献)

[复制链接]
发表于 2024-3-4 17:14:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zhangjinxuan 于 2024-3-6 08:52 编辑

Never gonna give you up. Never gonna let you down.

题目链接:https://www.luogu.com.cn/problem/P9912

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define int long long

  4. int n, Q, a[200001], ans[200001], rem[200001];
  5. map<int, vector<int>> pos;
  6. struct Query {
  7.         int l, r, x, id;
  8. } q[200001];
  9. map<int, vector<Query>> qs;

  10. struct Info {
  11.         int tot, lh, rh; // 最左边有没有块,最右边有没有块
  12. };
  13. Info add(const Info a, const Info b)  { // 注意该运算不满足交换律
  14.         if (a.tot + a.lh + a.rh == -3) return b;
  15.         if (b.tot + b.lh + b.rh == -3) return a;
  16.         return {a.tot + b.tot - (a.rh && b.lh), a.lh, b.rh};
  17. }

  18. namespace SGT {
  19.         Info res[2000003];
  20. #define ls(i) (i << 1)
  21. #define rs(i) (i << 1 | 1)
  22.         void build(int i, int l, int r) {
  23.                 if (l == r) return res[i] = {1, 1, 1}, void();
  24.                 int mid = (l + r) / 2; build(ls(i), l, mid); build(rs(i), mid + 1, r);
  25.                 res[i] = add(res[ls(i)], res[rs(i)]);
  26.         }
  27.         void update(int i, int l, int r, int qp) {
  28.                 if (l > qp || r < qp) return; int mid = (l + r) / 2;
  29.                 if (l == r && l == qp) return res[i] = {0, 0, 0}, void();
  30.                 update(ls(i), l, mid, qp); update(rs(i), mid + 1, r, qp);
  31.                 res[i] = add(res[ls(i)], res[rs(i)]);
  32.         }
  33.         Info query(int i, int l, int r, int ql, int qr) {
  34.                 if (l > qr || r < ql) return {-1, -1, -1};
  35.                 //printf("%d %d %d %d %d\n", l, r, res[i].tot, res[i].lh, res[i].rh);
  36.                 if (l >= ql && r <= qr) return res[i];
  37.                 int mid = (l + r) / 2;
  38.                 return add(query(ls(i), l, mid ,ql, qr), query(rs(i), mid + 1, r, ql, qr));
  39.         }
  40. }

  41. signed main() {
  42.         scanf("%lld%lld", &n, &Q);
  43.         vector<int> qss;
  44.         for (int i = 1; i <= n; ++i) {
  45.                 scanf("%lld", &a[i]);
  46.                 pos[a[i]].push_back(i);
  47.                 qss.push_back(a[i]);
  48.         }
  49.         sort(qss.begin(), qss.end());
  50.         auto enit = unique(qss.begin(), qss.end());
  51.         int minv = 1ll << 60;
  52.         for (int i = 1; i <= Q; ++i) {
  53.                 scanf("%lld%lld%lld", &q[i].l, &q[i].r, &q[i].x);
  54.                 if (q[i].x < qss[0]) q[i].x = -1;
  55.                 else q[i].x = qss[min((std::vector<long long>::size_type)(lower_bound(qss.begin(), enit, q[i].x + 1) - qss.begin() - 1), qss.size() - 1)];
  56.                 q[i].id = i; qs[q[i].x].push_back(q[i]);
  57.                 minv = min(minv, q[i].x);
  58.         }
  59.         for (int i = 1; i <= n; ++i) {
  60.                 if (a[i] < minv) pos[minv].push_back(i);
  61.         }
  62.         SGT::build(1, 1, n);
  63.         for (auto i : qs) {
  64.                 for (auto j : pos[i.first]) {
  65.                         if (rem[j]) continue;
  66.                         rem[j] = 1;
  67.                         SGT::update(1, 1, n, j);
  68.                 }
  69.                 for (auto j : i.second) {
  70.                         Info tmp = SGT::query(1, 1, n, j.l, j.r);
  71.                         ans[j.id] = tmp.tot;
  72.                         //printf("ans: %lld, %lld, %lld, %lld\n", j.id, tmp.tot, tmp.lh, tmp.rh);
  73.                 }
  74.         }
  75.         for (int i = 1; i <= Q; ++i) printf("%lld\n", ans[i]);
  76. }

复制代码


这是一个离线算法,大体思路如下:
  • 首先所有的询问的 x 参数,把 x 重新赋值为在 a 序列中比他小于等于的最大值,如果不存在就改成 0。
  • 然后按照询问参数 x 从小到大模拟涨水,对于每一次涨水,看看哪些点被淹没了,在线段树中作出对应的修改。
  • 最后查询区间,还原询问。


线段树记录的节点表示目前的岛屿组成极大未淹没连续子段的情况,tot 表示总数,lh 表示这个区间最左边的岛屿是否被淹没,rh 表示这个区间最右边的岛屿是否被淹没。

严重怀疑是第一步写错了,或者是线段树 query 返回 {-1, -1, -1} 这个地方。

第一次尝试写代码,结果全是错的。
最佳答案
2024-3-7 17:03:42
  1. 我这代码都超时,你那肯定超
  2. 不过这代码除了tle就是ac
  3. 代码应该没有问题,接下来看看要如何提高代码效率了

  4. 这洛谷最恶心的一点就是,他只告诉你错了,但是不告诉你在哪个数据上错了
  5. 这还调试个球
  6. 你只能去猜自己代码中可能的问题,没法调试
  7. 如果可以,换一个刷题网站吧
  8. 这洛谷太tm垃圾了
复制代码

  1. /*
  2. #include <iostream>

  3. using std::cin, std::cout, std::endl;

  4. int find(int n, const int *h, int l, int r, int x) {
  5.     --l, --r;
  6.     int count = 0;
  7.     while(true) {
  8.         while(l <= r) if(h[l++] > x) goto e;
  9.         return count;
  10. e:      while(l <= r) if(h[l++] <= x) break;
  11.         ++count;
  12.     }
  13. }

  14. int main() {
  15.     int n, q; cin >> n >> q;
  16.     int h[n]; for(int i = 0; i < n; ++i) cin >> h[i];
  17.     for(int i = 0; i < q; ++i) {
  18.         int l, r, x;
  19.         cin >> l >> r >> x;
  20.         int count = find(n, h, l, r, x);
  21.         cout << count << endl;
  22.     }
  23.     return 0;
  24. }
  25. */


  26. /*
  27. #include <iostream>

  28. using std::cin, std::cout, std::endl;

  29. int n, q, h[200000], l, r, x;
  30. int count, i;

  31. void find() {
  32.     --l, --r;
  33.     count = 0;
  34.     while(true) {
  35.         while(l <= r) if(h[l++] > x) goto e;
  36.         return;
  37. e:      while(l <= r) if(h[l++] <= x) break;
  38.         ++count;
  39.     }
  40. }

  41. int main() {
  42.     cin >> n >> q;
  43.     for(i = 0; i < n; ++i) cin >> h[i];
  44.     for(i = 0; i < q; ++i) {
  45.         cin >> l >> r >> x;
  46.         find(); cout << count << endl;
  47.     }
  48.     return 0;
  49. }
  50. */

  51. #include <cstdio>

  52. using std::scanf, std::printf;

  53. int n, q, h[200000], l, r, x;
  54. int count, i;

  55. __attribute((always_inline)) inline void find() {
  56.     --l, --r;
  57.     count = 0;
  58.     while(true) {
  59.         while(l <= r) if(h[l++] > x) goto e;
  60.         return;
  61. e:      while(l <= r) if(h[l++] <= x) break;
  62.         ++count;
  63.     }
  64. }

  65. int main() {
  66.     scanf("%d%d", &n, &q);
  67.     for(i = 0; i < n; ++i) scanf("%d", &h[i]);
  68.     for(i = 0; i < q; ++i) {
  69.         scanf("%d%d%d", &l, &r, &x);
  70.         find(); printf("%d\n", count);
  71.     }
  72.     return 0;
  73. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-3-4 17:15:56 | 显示全部楼层
FishC 发表于 2024-3-4 17:14
这段代码中存在一些问题:

1. 缺少头文件``和``,需要添加上去。

题目是这样的:

# [COCI 2023/2024 #2] Zatopljenje

## 题目描述

Mr. Malnar 有一张地形图,上面画着一个区域内每个位置的海拔高度。具体的,有 $n$ 个位置排成一排,第 $i$ 个位置高出海平面 $h_i$ 米。

海平面可能会上升。给定 $q$ 次询问,对于第 $i$ 次询问你需回答:如果海平面高度上升 $x_i$ 米,那么 $[l_i,r_i]$ 区间中会形成多少个岛?一个岛的定义为一个极长的,每个位置的高度都大于 $x_i$ 的段。

![](https://cdn.luogu.com.cn/upload/image_hosting/mffg52xn.png)

上图分别表示了样例 1 的第一组询问以及样例 2 的第二组询问。左图 $[2,5]$ 区间中有 $[2,2],[4,5]$ 两个岛,而右图中有 $[1,1],[4,4],[8,8],[10,10]$ 四个岛。

## 输入格式

第一行两个整数 $n,q$。

第二行 $n$ 个整数 $h_{1\sim n}$ 表示每个位置的初始海拔。

接下来 $q$ 行每行 $3$ 个整数 $l_i,r_i,x_i$ 表示一次询问。

## 输出格式

输出 $q$ 行,第 $i$ 行一个整数表示第 $i$ 次询问的答案。

## 样例 #1

### 样例输入 #1

```
6 3
2 4 2 3 4 1
2 5 2
3 5 3
3 4 4
```

### 样例输出 #1

```
2
1
0
```

## 样例 #2

### 样例输入 #2

```
10 3
5 0 3 4 2 0 1 6 3 5
3 9 1
1 10 3
1 10 2
```

### 样例输出 #2

```
2
4
3
```

## 提示

### 数据范围
|$\text{Subtask}$|分值|特殊性质|
|:-:|:-:|:-:|
|$1$|$10$|$n,q\le 2000$|
|$2$|$20$|$l_i=1,r_i=n$|
|$3$|$20$|存在 $p\in [1,n]$ 满足 $h_1\ge h_2\ge \cdots \ge h_p\le h_{p+1}\le \cdots \le h_n$|
|$4$|$60$|无|

对于所有数据,$1\le n,q\le 2\times 10^5$,$0\le h_i,x_i\le 10^9$,$1\le l_i\le r_i\le n$。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-6 08:41:58 | 显示全部楼层
我现在已经改出来了,但是不知道为什么原本的代码是错误的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-4 17:14:44 | 显示全部楼层
这段代码中存在一些问题:

1. 缺少头文件`<map>`和`<cstdio>`,需要添加上去。
2. `namespace SGT`中的函数`query`中缺少返回值,需要添加`return res;`。
3. `main`函数中对数组`pos`进行了操作,需要先声明一个数组才能使用。
4. 在调用`query`函数时,传入参数类型错误。应该传入四个整数作为参数,而不是一个`Query`结构体。
5. `query`函数中存在递归调用,但没有设置终止条件,可能会导致栈溢出。可以在开始处加上判断条件,如果区间范围不合法,则返回`{-1, -1, -1}`。
6. 在递归调用之前,应该先判断是否已经找到了答案,如果已经找到则直接返回结果。

修改后的代码如下:

  1. #include <iostream>
  2. #include <map>
  3. using namespace std;
  4. #define int long long

  5. int n, Q, a, ans, rem;
  6. map<int, int> pos;
  7. struct Query {
  8.     int l, r, x, id;
  9. } q;
  10. map<int, Query> qs;

  11. struct Info {
  12.     int tot, lh, rh; // 最左边有没有块,最右边有没有块
  13. };
  14. Info add(const Info a, const Info b)  { // 注意该运算不满足交换律
  15.     if (a.tot + a.lh + a.rh == -3) return b;
  16.     if (b.tot + b.lh + b.rh == -3) return a;
  17.     return {a.tot + b.tot - (a.rh && b.lh), a.lh, b.rh};
  18. }

  19. namespace SGT {
  20.     Info res;
  21. #define ls(i) (i << 1)
  22. #define rs(i) (i << 1 | 1)
  23.     void build(int i, int l, int r) {
  24.         if (l == r) {
  25.             if (!pos[l]) res = {0, -1, -1}; // 空位置
  26.             else res = {1, 1, 1}; // 有方块
  27.             return;
  28.         }
  29.         int mid = (l + r) >> 1;
  30.         build(ls(i), l, mid);
  31.         build(rs(i), mid + 1, r);
  32.         res = add(res, res);
  33.     }
  34.     Info query(int i, int l, int r, int ql, int qr) {
  35.         if (l > qr || r < ql) return {-1, -1, -1};
  36.         if (l >= ql && r <= qr) return res;
  37.         int mid = (l + r) >> 1;
  38.         Info res = add(query(ls(i), l, mid, ql, qr), query(rs(i), mid + 1, r, ql, qr));
  39.         return res;
  40.     }
  41. #undef ls
  42. #undef rs
  43. }

  44. signed main() {
  45.     cin >> n >> Q;
  46.     for (int i = 1; i <= n; ++i) {
  47.         cin >> a;
  48.         pos[a] = i;
  49.     }
  50.     for (int i = 1; i <= Q; ++i) {
  51.         cin >> q.l >> q.r >> q.x;
  52.         q.id = i;
  53.         qs[q.x] = q;
  54.     }
  55.     SGT::build(1, 1, n);
  56.     for (auto it = qs.begin(); it != qs.end(); ++it) {
  57.         Info info = SGT::query(1, 1, n, it->second.l, it->second.r);
  58.         int cnt = info.tot + info.lh + info.rh;
  59.         if (cnt < 0) continue;
  60.         ans += cnt;
  61.         SGT::modify(1, 1, n, it->second.l, it->second.r, 0);
  62.     }
  63.     cout << ans << endl;
  64.     return 0;
  65. }
复制代码


希望能帮到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-4 17:16:21 | 显示全部楼层
zhangjinxuan 发表于 2024-03-04 17:15
题目是这样的:

#  Zatopljenje

## 题目描述

...


根据题目描述,我们需要对每次询问进行处理。首先,我们可以使用一个数组`h`来保存每个位置的初始海拔高度。然后,我们逐个处理每次询问。

对于每个询问,我们需要找到海平面上升后形成的岛的数量。为了方便计算,我们可以将问题转化为求解海平面上升前所形成的水域的数量。

我们可以使用一个变量`water_level`来表示当前的海平面高度。初始时,`water_level`的值为0。我们从左到右遍历每个位置,如果该位置的海拔高度大于当前的`water_level`,则说明这是一个新的水域的起点,水域的数量加1,并更新`water_level`的值为该位置的海拔高度。如果该位置的海拔高度小于等于当前的`water_level`,则说明这是一个水域的一部分,不需要做任何操作。

接下来,我们需要根据每次询问给定的上升高度来计算岛的数量。假设当前的`water_level`为0,我们需要找到在海平面上升`xi`米后形成的岛的数量。我们可以使用二分搜索的方法来找到新的水域的起点,找到最后一个海拔高度小于等于`xi + water_level`的位置,将其设置为新的`water_level`,并将其后面的位置视为新的岛。新的岛的数量等于区间的长度减去最后一个水域的起点位置。

根据以上的思路,我们可以实现以下代码:

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;

  4. int main() {
  5.     int n, q;
  6.     cin >> n >> q;

  7.     vector<int> h(n); // 保存每个位置的初始海拔高度
  8.     for (int i = 0; i < n; i++) {
  9.         cin >> h[i];
  10.     }

  11.     int water_level = 0; // 当前海平面高度

  12.     // 遍历每次询问
  13.     for (int i = 0; i < q; i++) {
  14.         int l, r, x;
  15.         cin >> l >> r >> x;

  16.         // 计算海平面上升后形成的岛的数量
  17.         int islands = 0;

  18.         // 二分搜索找到新的水域的起点
  19.         int low = l - 1, high = r - 1;
  20.         while (low <= high) {
  21.             int mid = low + (high - low) / 2;
  22.             if (h[mid] <= x + water_level) {
  23.                 low = mid + 1;
  24.             } else {
  25.                 high = mid - 1;
  26.             }
  27.         }

  28.         // 更新水域的起点为最后一个小于等于 x+water_level 的位置
  29.         if (low < n && h[low] <= x + water_level) {
  30.             water_level = h[low];
  31.             islands = r - low - 1; // 岛的数量等于区间的长度减去水域的起点位置
  32.         }

  33.         cout << islands << endl;
  34.     }

  35.     return 0;
  36. }
复制代码


希望以上解答对你有帮助,如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-5 13:33:51 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-3-5 13:34:38 | 显示全部楼层


对不起,我之前的回答并没有给出完整的代码。以下是完整的代码实现:

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;

  4. // 找到最后一个小于等于target的位置
  5. int binary_search(vector<int>& nums, int target) {
  6.     int low = 0, high = nums.size() - 1;
  7.     while (low <= high) {
  8.         int mid = low + (high - low) / 2;
  9.         if (nums[mid] > target) {
  10.             high = mid - 1;
  11.         } else {
  12.             low = mid + 1;
  13.         }
  14.     }
  15.     return high;
  16. }

  17. int main() {
  18.     int n, q;
  19.     cin >> n >> q;
  20.    
  21.     vector<int> h(n); // 保存每个位置的初始海拔高度
  22.     for (int i = 0; i < n; i++) {
  23.         cin >> h[i];
  24.     }
  25.    
  26.     int water_level = 0; // 当前海平面高度
  27.    
  28.     // 遍历每次询问
  29.     for (int i = 0; i < q; i++) {
  30.         int l, r, x;
  31.         cin >> l >> r >> x;
  32.         
  33.         // 计算海平面上升后形成的岛的数量
  34.         int islands = 0;
  35.         
  36.         // 二分搜索找到新的水域的起点
  37.         int start = binary_search(h, x + water_level);
  38.         
  39.         // 新的water_level为x + water_level
  40.         water_level += x;
  41.         
  42.         // 计算岛的数量
  43.         islands = r - start - 1;
  44.         
  45.         cout << islands << endl;
  46.     }
  47.    
  48.     return 0;
  49. }
复制代码


希望这次的回答能够帮助到你!如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-6 08:42:08 | 显示全部楼层
zhangjinxuan 发表于 2024-03-06 08:41
我现在已经改出来了,但是不知道为什么原本的代码是错 ...


对不起,我之前的回答没有详细解释原始代码中的错误。以下是对原始代码错误的解释:

1. 缺少头文件 `#include <iostream>` 和 `#include <vector>`:这两个头文件分别用于输入输出和使用向量容器。
2. 没有正确处理每次询问的输入:原始代码中的输入方式不正确。每次询问涉及三个整数,应该使用 `cin` 来读取这三个整数。例如,`cin >> l >> r >> x;`。
3. 没有计算初始水域数量:在遍历每个位置之前,应该初始化 `int islands = 1;`,以便将第一个海拔高度大于当前水位的位置视为一个新的水域。
4. 未更新 `water_level` 的值:在找到新的水域起点后,需要将 `water_level` 的值更新为新的水位,即 `water_level += x;`。
5. 未输出每次询问的结果:在计算完每次询问的岛屿数量后,需要使用 `cout` 输出结果,例如 `cout << islands << endl;`。

通过以上的修改,可以得到正确的代码实现。抱歉给你带来了困扰。如果你有任何其他问题,请随时告诉我。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-7 12:55:38 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-3-7 12:55:53 | 显示全部楼层


非常抱歉,之前的回答还是有问题。我再次回顾一下原始代码,并给出修正后的版本。

根据题目描述,我们需要计算每次询问中上升海平面后形成的岛屿数量。具体思路如下:

1. 遍历每次询问,获取查询范围和上升高度。
2. 根据查询范围,计算初始水域的数量 `islands`,初始值为1(因为第一个位置一定是水域)。
3. 初始化当前的水位 `water_level` 为0。
4. 遍历查询范围内的每个位置:
   - 如果该位置的海拔高度大于当前水位 `water_level`,说明遇到了新的水域,将 `islands` 加1,并更新 `water_level` 为该位置的海拔高度。
   - 否则,继续遍历下一个位置。
5. 在计算完每次询问的岛屿数量后,输出结果。

以下是修正后的代码实现:

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;

  4. int main() {
  5.     int n, q;
  6.     cin >> n >> q;

  7.     vector<int> h(n); // 保存每个位置的初始海拔高度
  8.     for (int i = 0; i < n; i++) {
  9.         cin >> h[i];
  10.     }

  11.     // 遍历每次询问
  12.     for (int i = 0; i < q; i++) {
  13.         int l, r, x;
  14.         cin >> l >> r >> x;

  15.         int islands = 1; // 初始水域数量
  16.         int water_level = 0; // 当前水位

  17.         // 计算初始水域数量和当前水位
  18.         for (int j = l - 1; j < r; j++) {
  19.             if (h[j] > water_level) {
  20.                 islands++;
  21.                 water_level = h[j];
  22.             }
  23.         }

  24.         // 输出结果
  25.         cout << islands - 1 << endl;
  26.     }

  27.     return 0;
  28. }
复制代码


希望这次能够解决你的问题,如果还有其他疑问,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-7 17:03:42 | 显示全部楼层    本楼为最佳答案   
  1. 我这代码都超时,你那肯定超
  2. 不过这代码除了tle就是ac
  3. 代码应该没有问题,接下来看看要如何提高代码效率了

  4. 这洛谷最恶心的一点就是,他只告诉你错了,但是不告诉你在哪个数据上错了
  5. 这还调试个球
  6. 你只能去猜自己代码中可能的问题,没法调试
  7. 如果可以,换一个刷题网站吧
  8. 这洛谷太tm垃圾了
复制代码

  1. /*
  2. #include <iostream>

  3. using std::cin, std::cout, std::endl;

  4. int find(int n, const int *h, int l, int r, int x) {
  5.     --l, --r;
  6.     int count = 0;
  7.     while(true) {
  8.         while(l <= r) if(h[l++] > x) goto e;
  9.         return count;
  10. e:      while(l <= r) if(h[l++] <= x) break;
  11.         ++count;
  12.     }
  13. }

  14. int main() {
  15.     int n, q; cin >> n >> q;
  16.     int h[n]; for(int i = 0; i < n; ++i) cin >> h[i];
  17.     for(int i = 0; i < q; ++i) {
  18.         int l, r, x;
  19.         cin >> l >> r >> x;
  20.         int count = find(n, h, l, r, x);
  21.         cout << count << endl;
  22.     }
  23.     return 0;
  24. }
  25. */


  26. /*
  27. #include <iostream>

  28. using std::cin, std::cout, std::endl;

  29. int n, q, h[200000], l, r, x;
  30. int count, i;

  31. void find() {
  32.     --l, --r;
  33.     count = 0;
  34.     while(true) {
  35.         while(l <= r) if(h[l++] > x) goto e;
  36.         return;
  37. e:      while(l <= r) if(h[l++] <= x) break;
  38.         ++count;
  39.     }
  40. }

  41. int main() {
  42.     cin >> n >> q;
  43.     for(i = 0; i < n; ++i) cin >> h[i];
  44.     for(i = 0; i < q; ++i) {
  45.         cin >> l >> r >> x;
  46.         find(); cout << count << endl;
  47.     }
  48.     return 0;
  49. }
  50. */

  51. #include <cstdio>

  52. using std::scanf, std::printf;

  53. int n, q, h[200000], l, r, x;
  54. int count, i;

  55. __attribute((always_inline)) inline void find() {
  56.     --l, --r;
  57.     count = 0;
  58.     while(true) {
  59.         while(l <= r) if(h[l++] > x) goto e;
  60.         return;
  61. e:      while(l <= r) if(h[l++] <= x) break;
  62.         ++count;
  63.     }
  64. }

  65. int main() {
  66.     scanf("%d%d", &n, &q);
  67.     for(i = 0; i < n; ++i) scanf("%d", &h[i]);
  68.     for(i = 0; i < q; ++i) {
  69.         scanf("%d%d%d", &l, &r, &x);
  70.         find(); printf("%d\n", count);
  71.     }
  72.     return 0;
  73. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-7 17:05:35 | 显示全部楼层
  1. 第一个代码写的多好,非要为了执行效率,把代码写的连你自己都看不懂了,这就好?
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-7 18:17:50 | 显示全部楼层
本帖最后由 人造人 于 2024-3-7 18:21 编辑
  1. 他这数据还不是一次性给出?
  2. 把代码都写成这样了,还是不行
  3. 我这扫描一遍都超时?
  4. 这个题有更好的算法?
  5. tm的,他不给输入数据,我不知道我的程序在什么数据上出错了,没法调试
  6. 我不玩了,谁爱玩谁去玩吧
复制代码

  1. /*
  2. #include <iostream>

  3. using std::cin, std::cout, std::endl;

  4. int find(int n, const int *h, int l, int r, int x) {
  5.     --l, --r;
  6.     int count = 0;
  7.     while(true) {
  8.         while(l <= r) if(h[l++] > x) goto e;
  9.         return count;
  10. e:      while(l <= r) if(h[l++] <= x) break;
  11.         ++count;
  12.     }
  13. }

  14. int main() {
  15.     int n, q; cin >> n >> q;
  16.     int h[n]; for(int i = 0; i < n; ++i) cin >> h[i];
  17.     for(int i = 0; i < q; ++i) {
  18.         int l, r, x;
  19.         cin >> l >> r >> x;
  20.         int count = find(n, h, l, r, x);
  21.         cout << count << endl;
  22.     }
  23.     return 0;
  24. }
  25. */


  26. /*
  27. #include <iostream>

  28. using std::cin, std::cout, std::endl;

  29. int n, q, h[200000], l, r, x;
  30. int count, i;

  31. void find() {
  32.     --l, --r;
  33.     count = 0;
  34.     while(true) {
  35.         while(l <= r) if(h[l++] > x) goto e;
  36.         return;
  37. e:      while(l <= r) if(h[l++] <= x) break;
  38.         ++count;
  39.     }
  40. }

  41. int main() {
  42.     cin >> n >> q;
  43.     for(i = 0; i < n; ++i) cin >> h[i];
  44.     for(i = 0; i < q; ++i) {
  45.         cin >> l >> r >> x;
  46.         find(); cout << count << endl;
  47.     }
  48.     return 0;
  49. }
  50. */

  51. /*
  52. #include <cstdio>

  53. using std::scanf, std::printf;

  54. int n, q, h[200000], l, r, x;
  55. int count, i;

  56. __attribute((always_inline)) inline void find() {
  57.     --l, --r;
  58.     count = 0;
  59.     while(true) {
  60.         while(l <= r) if(h[l++] > x) goto e;
  61.         return;
  62. e:      while(l <= r) if(h[l++] <= x) break;
  63.         ++count;
  64.     }
  65. }

  66. int main() {
  67.     scanf("%d%d", &n, &q);
  68.     for(i = 0; i < n; ++i) scanf("%d", &h[i]);
  69.     for(i = 0; i < q; ++i) {
  70.         scanf("%d%d%d", &l, &r, &x);
  71.         find(); printf("%d\n", count);
  72.     }
  73.     return 0;
  74. }
  75. */

  76. #include <stdio.h>
  77. #include <stdbool.h>
  78. #include <ctype.h>
  79. #include <unistd.h>

  80. int n, q, h[200000], l, r, x;
  81. int count, i;

  82. #define ISIZE 0xf00000000
  83. char *ibuf;
  84. long long int ipos;

  85. #define OSIZE 30
  86. char obuf[OSIZE];
  87. int opos;

  88. __attribute((always_inline)) inline void find() {
  89.     --l, --r;
  90.     count = 0;
  91.     while(true) {
  92.         while(l <= r) if(h[l++] > x) goto e;
  93.         return;
  94. e:      while(l <= r) if(h[l++] <= x) break;
  95.         ++count;
  96.     }
  97. }

  98. __attribute((always_inline)) inline void print_count() {
  99.     opos = OSIZE - 2; obuf[opos] = '0';
  100.     while(count) {
  101.         obuf[opos--] = count % 10 + '0';
  102.         count /= 10;
  103.     }
  104.     write(1, &obuf[opos], OSIZE - opos);
  105. }

  106. __attribute((always_inline)) inline void read_number(int *n) {
  107.     while(!isdigit(ibuf[ipos])) ++ipos;
  108.     *n = 0;
  109.     while(isdigit(ibuf[ipos])) *n = *n * 10 + (ibuf[ipos++] - '0');
  110. }

  111. int main() {
  112.     ibuf = sbrk(ISIZE);
  113.     if(ibuf == (void *)-1) return -1;
  114.     obuf[OSIZE - 1] = '\n';
  115.     read(0, ibuf, ISIZE);
  116.     read_number(&n);
  117.     read_number(&q);
  118.     for(i = 0; i < n; ++i) read_number(&h[i]);
  119.     for(i = 0; i < q; ++i) {
  120.         read_number(&l); read_number(&r); read_number(&x);
  121.         find(); print_count();
  122.     }
  123.     return 0;
  124. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-7 19:30:28 | 显示全部楼层

洛谷某些打印输出题用C做,自己测试输出完全没问题,但是放洛谷上就全WA,一改C++就过了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-7 19:41:48 | 显示全部楼层
yinda_peng 发表于 2024-3-7 19:30
洛谷某些打印输出题用C做,自己测试输出完全没问题,但是放洛谷上就全WA,一改C++就 ...

主要是他不给看出错的数据,没法调试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-7 19:45:02 | 显示全部楼层
人造人 发表于 2024-3-7 19:41
主要是他不给看出错的数据,没法调试

对,虽然可以下载第一个出错数据,但限制次数,不理解这样做的意义,力扣就好多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-7 20:00:14 | 显示全部楼层
yinda_peng 发表于 2024-3-7 19:45
对,虽然可以下载第一个出错数据,但限制次数,不理解这样做的意义,力扣就好多了

我这边都没有下载第一个的选项
自己作死就一定会死
他这么做还有谁会用他
谁也不用他,他就死了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-8 08:12:57 | 显示全部楼层
人造人 发表于 2024-3-7 20:00
我这边都没有下载第一个的选项
自己作死就一定会死
他这么做还有谁会用他

洛谷是这样的,COCI 都公开数据了这个洛谷都不让你下,不知道为什么。

我的代码考虑离线询问,从小到大模拟涨水的过程,对每一次淹没的点更新答案,并使用线段树查询,可以达到比双重循环更优秀的效果,但是不知道为什么这样写错了,只有从大到小才是对的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-8 08:16:51 | 显示全部楼层
差不多得了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-8 12:57:40 | 显示全部楼层
  1. 说到线段树,我再研究研究,再试试
  2. 我又有一个想法,只是在合并区间这里有点问题,我需要再研究研究
  3. ^_^
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 19:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表