首页 > 其他分享 >AtCoder Beginner Contest 355 (E,F)

AtCoder Beginner Contest 355 (E,F)

时间:2024-06-01 17:32:42浏览次数:13  
标签:pre AtCoder Beginner int sum 然后 355 query 100

总结:

这把B都错题了一直Wa,然后队友告诉我说F貌似可做,写了半个小时F发现题目读假了,于是四题下班。


E - Guess the Sum

  1. 题目大意:
  • 给定一个隐藏的、长度为N的数组,下标从0开始,题目给定L,R,要你用最少的询问次数求出\(\sum_{i = L}^{R}a_{i}\)。
  • 对于每次询问,可以选择一个 i 和 j ,然后询${\textstyle\sum_{l}^{r}}ai,l = 2 ^ i * i,r = 2 ^ i * (j + 1) $ 。
  1. 思路分析:
  • 一开始我想的是从起点开始,对于每个点枚举最大能够整除的$2^{i} $,然后直接能跳就跳,然后我Wa了,不知道为啥,当时做的时候,没想过还能够把当前的左端点变小的。然后就没思路了,去找别人的题解了。
  • 假设长度为3,现在我要问 \([1, 7]\), 如果以我之前的思路,那答案会这么变化 $(1, 2), (2, 3), (4, 7) $, 这样问了3次,但能不能更优呢?
  • 其实可以先问 \([0, 8)\),再问\([0, 1)\),然后把0给减掉就可以了,这就有点奇怪了,既然能往回走,就很难去想个策略去解决这个问题。题目最多只有\(2 ^ {N}\)个点,所以我们可以尝试去搜索,整张图只有\(N\cdot 2^{N}\)条边,所以建图然后从起点广搜就可以了。然后对于每个点记录前驱就可以找到整个路径了。然后建图的时候对于每个点只能走\(2 ^ {i}\),所以直接枚举次数,像 $ 2 ^ {1} - 2 ^ {2} - 2 ^ {3}$这么连边就可以了.
    3.代码:
void solve() {
    int N, L, R;cin >> N >> L >> R;
    int up = 1 << N;
    vvi g(up + 2, vi());
    for(int i = 0; i <= N; i++) {
        for(int l = 0; l < up; l += (1 << i)) {
            int r = l + (1 << i);
            g[l].push_back(r);
            g[r].push_back(l);
        }
    }
    queue<int> q;
    vi pre(up + 1, -1);
    vpi query;
    q.push(L);
    pre[L] = 0;
    while(!q.empty()) {
        int t = q.front();
        q.pop();
        if(t == R + 1) break;
        for(auto v : g[t]) {
            if(pre[v] != -1) continue;
            pre[v] = t;
            q.push(v);
        }
    }

    for(int i = R + 1; i != L; i = pre[i]) {
        query.push_back({pre[i], i});
    }
    reverse(query.begin(), query.end());
    int sum = 0;
    for(auto [l, r] : query) {
        int flag = l > r ? -1 : 1;
        if(flag == -1) swap(l, r);
        int i = __builtin_ctz(r - l);
        int j = l >> i;
        cout << "? " << i << " " << j << endl;
        int t;cin >> t;
        sum += t * flag;        
    }
    sum = (sum % 100 + 100) % 100;
    cout << "! " << sum << endl;
}

标签:pre,AtCoder,Beginner,int,sum,然后,355,query,100
From: https://www.cnblogs.com/orzkeyhacker/p/18226194

相关文章

  • Atcoder ABC355 C~F
    C出题人太善良了,加强到\(10^5\)都没问题。考虑维护每条横线竖线两条对角线上被标记的点的个数,每次标记点后,判断是否有线上点全被标记。再考虑如何将点编号转为坐标,记编号为\(t\),推柿子:\[(x-1)\timesn+y=t\]\[nx+y=t+n\]\[x=\frac{t+n-y}{n}\]等同于找到\(y\)使得:\[n......
  • AtCoder Beginner Contest 328
    A-NotTooHard#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;#defineinti64usingvi=vector<int>;i32main(){ ios::sync_with_stdio(false),cin.tie(nullptr); intn,x; cin>>n&g......
  • 查阅相关资料, 了解什么是scrum中的3355?
    在Scrum中,3355是一个用于描述其核心组成部分的模型,具体包括三个核心角色、三个工件、五个关键事件和五个价值观。下面是对Scrum中3355的详细解释:三个核心角色产品负责人(ProductOwner):主要负责确定产品的功能和达到要求的标准。指定软件的发布日期和交付的内容。有权力接受或......
  • ABC355
    E将所有的下标作为点,建一张无向图。当且仅当可以询问\([l,r]\)时,在点\(l\)和\(r+1\)之间连一条边。可以发现能求出\([L,R]\)的和等价于\(L\)与\(R+1\)连通,且最少询问次数等于两点间最短路径边数。具体实现是容易的。F边权很小,提示我们可以暴力枚举和替换边。开......
  • AtCoder Beginner Contest 124
    A-Buttons#include<bits/stdc++.h>usingnamespacestd;intmain(){ inta,b; cin>>a>>b; intres=0; if(a>b)res+=a,a--; elseres+=b,b--; if(a>b)res+=a,a--; elseres+=b,b--; cout<<res......
  • abc 355 F - MST Query
    题目链接:https://atcoder.jp/contests/abc355/tasks/abc355_f题目要求动态维护最小生成树.那么我们考虑朴素的Kruskal算法:将边从小到大排序,不断加边,用并查集维护联通块,加边加到整张图联通(联通块数量为1)为止,最后的答案就是从小到大遍历边权将边的数量*当前边权相加起来......
  • ABC 355 D题Intersecting Intervals
    题意现在有n条线段,每条线段的左端点和右端点依次给出,求有多少对线段有交集。思路考虑正难则反的想法,我们考虑着n条线段全部两两相交的时候,那么答案就是(n-1)*n/2,现在我们要求出有多少对线段是不相交的。当两条线段不相交的时候,显然有其中一条线段的左端点严格大于另一条线......
  • AtCoder abc325D
    原题链接ProblemStatementThereare\(N\)productslabeled\(1\)to\(N\)flowingonaconveyorbelt.AKeyenceprinterisattachedtotheconveyorbelt,andproduct\(i\)enterstherangeoftheprinter\(T_i\)microsecondsfromnowandleavesit......
  • ABC355 D区间相交问题
    ABC355D区间相交问题题意给出n个区间,每个区间给出左端点(l)和右端点(r),判断有多少区间成对相交。分析如果我们直接暴力查找每个区间是否和别的区间相交,那么时间复杂度就是O(\(n^2\)),肯定是过不了的。考虑如何优化,通过题意,可以发现优化的关键在于区间相交的判定方式,对于任意两......
  • 关于Scrum中的"3355"
    3355是敏捷开发中Scrum框架的一个核心概念,它代表了Scrum框架的三个角色、三个工件、五个关键事件和五个价值观。三个角色:ProductOwner(产品负责人):负责定义需求,确定需求优先级,定义需求验收标准,定义产品发布内容与日期。ScrumMaster(敏捷教练):帮助团队遵循Scrum框架,持续改进......