卡常是不是Ynoi传统艺能啊
查看原帖
卡常是不是Ynoi传统艺能啊
684254
Rain_chr楼主2023/12/29 20:38

线段树的单log,2e6,4s,竟然被卡了???

虽说线段树里套了个广义矩阵乘法,但是我只留下了有值的位置啊,一次也就5次加法。

2e6 * 线段树的log * 线段树的8倍常数 * 矩阵乘法5倍常数也只有8e8,感觉4s还是比较轻松的啊???

搞得最后我跟暴力同分。

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
int n,q;
int a[N],lst[N],pos[N];
const int inf=-1000000000;
struct querys
{
    int l,r,id;
}ask[N];
int ans[N];
inline bool cmp(querys x,querys y)
{
    return x.r<y.r;
}
struct Vector
{
    int one,two,thr;
    inline Vector(){one=two=thr=0;}
    inline Vector(int x,int y,int z){one=x,two=y,thr=z;}
    inline Vector operator +(const Vector& y) const
    {
        return (Vector){max(one,y.one),max(two,y.two),max(thr,y.thr)};
    }
}t[N<<2];
struct Matrix
{
    int a00,a11,a21,a22;
    inline Matrix(){a00=a11=a22=0,a21=-1e9;}
    inline void clear(){a00=a11=a22=0,a21=-1e9;}
    inline Vector operator *(const Vector& y) const
    {
        return (Vector){a00+y.one,a11+y.two,max(inf,max(a21+y.two,a22+y.thr))};
    }
    inline Matrix operator *(const Matrix& y) const
    {
        Matrix ans;
        ans.a00=a00+y.a00;
        ans.a11=a11+y.a11;
        ans.a21=max(a21+y.a11,a22+y.a21);
        ans.a22=a22+y.a22;
        ans.a21=ans.a21<0?inf:ans.a21;
        ans.a22=ans.a22<0?inf:ans.a22;
        return ans;
    }
}tag[N<<2];
bitset<N<<2> book;
inline void pushdown(int x)
{
    if(!book[x]) return ;
    book[x<<1]=book[x<<1|1]=1;
    tag[x<<1]=tag[x]*tag[x<<1],tag[x<<1|1]=tag[x]*tag[x<<1|1];
    t[x<<1]=tag[x]*t[x<<1],t[x<<1|1]=tag[x]*t[x<<1|1];
    book[x]=0;
    tag[x].clear();
}
void update(int x,int l,int r,int L,int R,Matrix v)
{
    if(L<=l&&r<=R)
    {
        tag[x]=v*tag[x];
        t[x]=v*t[x];
        book[x]=1;
    }
    else
    {
        pushdown(x);
        int mid=(l+r)>>1;
        if(L<=mid) update(x<<1,l,mid,L,R,v);
        if(mid+1<=R) update(x<<1|1,mid+1,r,L,R,v);
        t[x]=t[x<<1]+t[x<<1|1];
    }
}
int queryc(int x,int l,int r,int pos)
{
    if(l==r) return t[x].one;
    else
    {
        pushdown(x);
        int mid=(l+r)>>1;
        if(pos<=mid) return queryc(x<<1,l,mid,pos);
        else return queryc(x<<1|1,mid+1,r,pos);
    }
}
int queryhis(int x,int l,int r,int L,int R)
{
    if(L<=l&&r<=R) return t[x].thr;
    else
    {
        pushdown(x);
        int mid=(l+r)>>1,k=0;
        if(L<=mid) k=max(k,queryhis(x<<1,l,mid,L,R));
        if(mid+1<=R) k=max(k,queryhis(x<<1|1,mid+1,r,L,R));
        return k;
    }
}
int querymax(int x,int l,int r,int k)
{
    if(t[x].one<k) return t[x].two;
    if(l==r) return 0;
    pushdown(x);
    int mid=(l+r)>>1;
    if(t[x<<1|1].one>=k) return querymax(x<<1|1,mid+1,r,k);
    else return max(t[x<<1|1].two,querymax(x<<1,l,mid,k));
}
signed main()
{
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>q;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        lst[i]=pos[a[i]];
        pos[a[i]]=i;
    }
    for(int i=1;i<=q;i++)
        cin>>ask[i].l>>ask[i].r,ask[i].id=i;
    sort(ask+1,ask+1+q,cmp);
    int p=1;
    for(int i=1;i<=n;i++)
    {
        Matrix v;
        v.a11=1;
        if(lst[i]) update(1,1,n,1,lst[i],v);
        v.clear();
        v.a00=v.a11=1,v.a21=0,v.a22=-1e9;
        update(1,1,n,lst[i]+1,i,v);
        while(p<=q&&ask[p].r==i) 
        {
            ans[ask[p].id]=max(queryhis(1,1,n,ask[p].l,ask[p].r),querymax(1,1,n,queryc(1,1,n,ask[p].l)));
            p++;
        }
    }
    for(int i=1;i<=q;i++) cout<<ans[i]<<'\n';
    return 0;
}
2023/12/29 20:38
加载中...