首页 > 其他分享 >树状数组模拟_ABC340_E - Mancala 2

树状数组模拟_ABC340_E - Mancala 2

时间:2024-02-13 20:11:34浏览次数:35  
标签:const Mancala 树状 int ll hand ABC340 start define

目录

问题简述

原题参考:E - Mancala 2
初始给出长度为n、m的数组a、b,要求给出m次操作后的数组a,每一次的操作流程如下:

  1. 设定变量c = 0;
  2. 取出a[b[i]]中的数字
  3. 保证手上有一个球的情况下进行以下操作:
    • c++
    • 向a[(b[i]+c)%n]中放1

可以看原题,原题有一个动画演示

思路分析

首先吐槽一手,发现做了这个题,我觉得我应该提高一下我的阅读理解能力,说实话,这个题目我当时看了很久,而且还读假了,稍后说。分析一下题目,大致就是一个模拟的过程,首先是取出一个位置的数字,做单点修改,然后开始向指定位置开始放数字,大致可以看作是一个区间修改的操作;第一次做的时候脑子一抽,想着只要输出最后的数组即可,所以想着直接用差分数组来做,写了一大半突然想起这个单点修改的事,更蠢的是,当时还想当然的把单点修改作为区间长为1的区间修改即可,等写完了,突然想起来,我在修改之前还要查,这下好了,直接tle,以后还是少偷懒。第二天起来补题,开始用树状数组写,第一遍写完之后结果样例都没过,当时就懵b了,开始调,发现动画里面拿的位置和我输出的不一样,更懵了,然后我就发现了,读错题了!!!,c每次都要重置(但是我得说一句,不重置的做法恶心一点),改了之后,样例倒是过了,交了一发,re!!!真是难绷,当时暂时也没看出来什么,以为是哪里的指针越界了,看了好久也没看出来,直到后面发现一个查询前缀和的变量可能爆了,但是爆了不应该是wa嘛,改了之后我也没报多大希望能ac,结果那13个re点过了,为什么爆数据是re[微笑]

参考代码

#include <bits/stdc++.h>
using namespace std;
#define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define pll pair<long long, long long>
#define pii pair<int, int>
#define vi vector<int>
#define vl vector<long long>
#define ll long long
#define ull unsigned long long
const ll INF = 9187201950435737471;
const int inf = 2139062143;
const ll mod = 1e9 + 7;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int N = 1e6+7;
ll n, m, a[N], b[N], pre = 0, tmp;
ll lowbit(ll x) {return x&-x;}
void change(ll i, ll x) {
    for(; i<=n; i+=lowbit(i)) a[i] += x;
} 
ll query(ll i) {
    ll res = 0;
    for(; i>0; i-=lowbit(i)) res += a[i];
    return res;
}
void solve() {
    cin >> n >> m;
    for(int i=1; i<=n; i++) {
        cin >> tmp;
        change(i, tmp-pre);
        pre = tmp;
    }
    for(int i=1; i<=m; i++) { 
        //说起来,这个b数组也不用记录,用个变量就行了
        cin >> b[i];
        ll hand = query(b[i]+1);
        //单点修改
        change(b[i]+1, -hand), change(b[i]+2, hand);
        int start = b[i] + 1 + 1;
        //这里是整体修改
        if(start > n) start %= n;
        if(!start) start = n;
        if(hand >= n) {
            change(1, hand/n);
            hand %= n;
        }
        //这里是分为是否会折返修改的讨论
        if(hand+start <= n+1) {
            change(start, 1), change(start+hand, -1);
        }
        else {
            change(start, 1);
            change(1, 1), change(hand+start-n, -1);
        }
    }
    for(int i=1; i<=n; i++) cout << query(i) << " \n"[i==n];
}
int main() {
#ifdef xrl
    freopen("in.txt", "r", stdin), freopen("out.txt", "w", stdout);
#endif
    FAST_IO;
    int t = 1;
    //cin >> t;
    while(t --) solve();
#ifdef xrl
    cout << "Time used = " << (double)(clock() * 1.0 / CLOCKS_PER_SEC) << "s";
#endif
    return 0;
}

做题反思

不得不说的必定是int牢底啊,又爆掉了,害我调了不少时间,苦思冥想一整天,不开longlong见祖宗;其次就是那个读错的c,我的语文水平已经到达这种地步了嘛,vocal,那这是真难绷

标签:const,Mancala,树状,int,ll,hand,ABC340,start,define
From: https://www.cnblogs.com/notalking569/p/18014784

相关文章

  • 三角形向量公式_ABC340_F - S = 1
    目录题目概述思路分析参考代码做题反思题目概述原题参考F-S=1给出坐标(A,B),问是否存在坐标(X,Y),使得这两个点和原点围起来的三角形的面积是1,如果存在,输出一组解,否则输出-1思路分析结论+板子,没什么好分析的,想到了就好写,利用向量的叉乘求解三角形的面积,因为给出的点中有一个原......
  • Atcoder ABC340(A-D)
    A题题意:给出一个首项为A,尾项为B,公差为D的算数序列,要求输出符合条件的序列思路:只需要从首项开始每次加上公差输出即可代码:#include<bits/stdc++.h>#defineiosios::sync_with_stdio(false);cin.tie(0);cout.tie(0)usingnamespacestd;intadd(intx,inty){returnx......
  • 树状数组区间修改区间查询
    树状数组区间修改区间查询问题——两种操作给定\(l,r,x\),将\([l,r]\)这个区间内的所有值都加上\(x\)给定\(l,r\)求出\([l,r]\)的区间和这道题肯定要用前缀和和差分,那么大体框架可以出来了//操作一:update(l,x),update(r+1,-x);//操作二query(r)-query(l......
  • ABC340G Leaf Color
    题意给定一棵树\(T\),包含\(n\)个节点,每个节点有颜色。求有多少个\(T\)的导出子图\(T'\),满足\(T'\)中的叶子节点颜色相同。答案对\(998244353\)取模。\(n\le2\times10^5\)。分析由于叶子节点的限制极其特殊,考虑从叶子的角度思考问题。如果知道了叶子节点的集合,那......
  • ABC340 E&F
    E每次操作的本质:将\(b_i\)盒子的球数置为\(0\),设取出球数为\(c\)。若\(n-b_i\gec\),则给区间\([b_i+1,b_i+c]\)球数加1。否则,先给\([b_i+1,n]\)加1,再全局加\(\frac{c-n+b_i}{n}\),设最终剩下的球数为\(c'(c'<n)\),给\([1,c']\)球数加1。使用任何可以维护区间......
  • ABC340
    Alink模拟。Blink模拟指针。Clink记忆化搜索。时间复杂度证明可以从一个奇数分多遍以后只会有两种数这一角度入手。Dlink由于每次只能选择一种,于是可以将选择变成连边,进行最短路。Elink线段树入门。取余操作本身就是一个环。注意题目中的操作是从\(0\simn-1\)。......
  • ABC340
    \(\huge{C}\)link首先,考虑暴力,用一个堆,存所有数,每次拿出最大的数,拆开加入堆,计入答案,直到最大的\(\le1\),时间复杂度\(O(\text{不能过})\)。考虑想求出\(n\),要什么。求\(n\)一定是第一次把\(n\)拆成\(\lfloor{\frac{n}{2}}\rfloor\)和\(\lceil{\frac{n}{2}}\rceil\),答案加上\(n......
  • ABC340
    T1:ArithmeticProgression模拟代码实现a,b,d=map(int,input().split())foriinrange(a,b+1,d):print(i,end='')T2:Append模拟代码实现q=int(input())a=[]forqiinrange(q):type,x=map(int,input().split())iftype==1:......
  • AtCoder-abc340_f题解
    题意简述给定整数\(x,y\),询问是否存在整数\(a,b\),满足:\(-10^{18}\lea,b\le10^{18}\)。由\((0,0),(x,y),(a,b)\)三点构成的三角形面积为\(1\)。如果存在,输出任意一组;否则输出-1。思路先假设\(x,y,a,b\)都是正数。那么图大概是这样:此时红色三角形的面积就......
  • ABC340
    E我们可以知道每一个点在每一轮加多少,具体如下:假如现在操作的点的为\(k\)。那么所有的数都至少会加\(\dfrac{A_k}{n}\)。但是肯定有剩的,剩了\(A_k\modn\)。很明显,\(A_k\modn\)会分给接下来的\(A_k\modn\)个数。这样我们就可以知道每个点每轮加多少了。然后用线段......