【BZOJ】2002 彈飛綿羊 分塊

【分析1】分塊—分段,詳見鄒逍遙《淺談分塊在一類在線問題中的應用》的第一道

【代碼1】分段
/**************************************************************
    Problem: 2002
    User: y20070316
    Language: C++
    Result: Accepted
    Time:5236 ms
    Memory:4212 kb
****************************************************************/
 
#include <bits/stdc++.h>
using namespace std;
 
const int N=200010;
const int BLOCK_SIZE=500;
const int BLOCK_NUMBER=500;
 
int n,m,unit;
struct Block
{
    int w[BLOCK_NUMBER];
    int len[BLOCK_NUMBER];
    int anc[BLOCK_NUMBER];
}ud_list[BLOCK_SIZE];
 
inline int Read(void)
{
    int s=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) s=s*10+c-'0';
    return s*f;
}
 
void Caculate(int nowBlock)
{
    int preCnt=(nowBlock-1)*unit,r=min(unit,n-(nowBlock-1)*unit);
    for (int i=r;i>=1;i--)
        if (i+ud_list[nowBlock].w[i]<=r)
        {
            ud_list[nowBlock].anc[i]=ud_list[nowBlock].anc[i+ud_list[nowBlock].w[i]];
            ud_list[nowBlock].len[i]=ud_list[nowBlock].len[i+ud_list[nowBlock].w[i]]+1;
        }
        else
        {
            ud_list[nowBlock].anc[i]=i;
            ud_list[nowBlock].len[i]=1;
        }
}
 
inline void Find(int x,int &nowBlock,int &nowPos)
{
    if (x>n)
    {
        nowBlock=n+1;
        nowPos=n+1;
    }
    else
    {
        nowBlock=(x-1)/unit+1;
        nowPos=x-(nowBlock-1)*unit;
    }
}
 
int Query(int x)
{
    int nowBlock,nowPos,sumLen=0;
    Find(x,nowBlock,nowPos);
    for (;nowBlock!=n+1&&nowPos!=n+1;)
    {
        sumLen+=ud_list[nowBlock].len[nowPos];
        Find((nowBlock-1)*unit+ud_list[nowBlock].anc[nowPos]+ud_list[nowBlock].w[ud_list[nowBlock].anc[nowPos]],nowBlock,nowPos);
    }
    return sumLen;
}
 
int main(void)
{
    int nowBlock=0,nowPos;
    n=Read();
    unit=sqrt(n);
    for (int i=1;i<=n;i++)
    {
        if (i%unit==1) nowBlock++,nowPos=0;
        ud_list[nowBlock].w[++nowPos]=Read();
    }
    for (int i=1;(i-1)*unit<n;i++) Caculate(i);
     
    int k,x;
    m=Read();
    for (int i=1;i<=m;i++)
    {
        k=Read(),x=Read()+1;
        if (k==1)
            printf("%d\n",Query(x));
        else
        {
            Find(x,nowBlock,nowPos);
            ud_list[nowBlock].w[nowPos]=Read();
            Caculate(nowBlock);
        }
    }
     
    return 0;
}

發佈了137 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章