BZOJ 3922 Karin的弹幕

Posted on 2017-01-21 17:57  ziliuziliu  阅读(120)  评论(0编辑  收藏  举报

400题留念。

话说这题真是的。。。浪费表情。

算了一下复杂度最好的都要n√nlogn啊。。。这个7w闹哪样。

然而看了一眼题解,按5分。

wtf我还以为有高论啊。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 70050
using namespace std;
int n,m,a[maxn],tab[maxn][6],bel[maxn][6],root[6],ls[maxn<<5],rs[maxn<<5],mx[maxn<<5],tot=0;
int type,x,y;
void build(int &now,int left,int right,int type)
{
    now=++tot;
    if (left==right) {mx[now]=a[bel[left][type]];return;}
    int mid=(left+right)>>1;
    build(ls[now],left,mid,type);
    build(rs[now],mid+1,right,type);
    mx[now]=max(mx[ls[now]],mx[rs[now]]);
}
void modify(int now,int left,int right,int pos,int val)
{
    if (left==right) {mx[now]=val;return;}
    int mid=(left+right)>>1;
    if (pos<=mid) modify(ls[now],left,mid,pos,val);
    else modify(rs[now],mid+1,right,pos,val);
    mx[now]=max(mx[ls[now]],mx[rs[now]]);
}
int ask(int now,int left,int right,int l,int r)
{
    if ((left==l) && (right==r)) return mx[now];
    int mid=(left+right)>>1;
    if (r<=mid) return ask(ls[now],left,mid,l,r);
    else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r);
    else return max(ask(ls[now],left,mid,l,mid),ask(rs[now],mid+1,right,mid+1,r)); 
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    for (int i=1;i<=5;i++)
    {
        int tot=0;
        for (int j=1;j<=i;j++)
        {
            int now=j;tot++;tab[now][i]=tot;bel[tot][i]=now;
            while (now+i<=n)
            {
                now+=i;tot++;
                tab[now][i]=tot;bel[tot][i]=now;
            }
        }
    }
    for (int i=1;i<=5;i++) build(root[i],1,n,i);
    scanf("%d",&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&type,&x,&y);
        if (!type)
        {
            a[x]+=y;
            for (int j=1;j<=5;j++) modify(root[j],1,n,tab[x][j],a[x]);
        }
        else
        {
            if (y<=5)
            {
                int now=n;
                while (now%y!=x%y) now--;
                printf("%d\n",ask(root[y],1,n,tab[x][y],tab[now][y]));
            }
            else
            {
                int ans=a[x];
                while (x+y<=n) {x+=y;ans=max(ans,a[x]);}
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}