Codeforces Round #549 (Div. 1) B. Lynyrd Skynyrd(倍增)

题面

按照贪心策略,枚举以每个位置为结尾,则往前遍历,找到它的前一个数字最近的出现位置,然后往前跳n-1步,倍增判断一下

跳到了哪个点。然后线段树查询一下区间最大值即可。

#include
using namespace std;
const int maxn=2e5+10;
vectorG[maxn];
int n,m,Q,a[maxn],has[maxn];
int f[maxn][22],lg[maxn],vis[maxn];
int tree[maxn<<2],dep[maxn];
string s;
void update(int L,int C,int l,int r,int rt)
{
    if(l==r)
    {
        tree[rt]=C;
        return;
    }
    int mid=(l+r)/2;
    if(L<=mid) update(L,C,l,mid,rt<<1);
    else update(L,C,mid+1,r,rt<<1|1);
    tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R) return tree[rt];
    int ans=0,mid=(l+r)/2;
    if(L<=mid) ans=max(ans,query(L,R,l,mid,rt<<1));
    if(R>mid) ans=max(ans,query(L,R,mid+1,r,rt<<1|1));
    return ans;
}
int cal(int v,int d)
{
    if(d<1) return 0;
    while(dep[v]>d)
    {
        int h=lg[dep[v]-d];
        v=f[v][h];
    }
    return v;
}
int main()
{
    for(int i=2;i=l) s+='1';
        else s+='0';
    }
    cout<

 

你可能感兴趣的:(倍增)