50分 TLE 了一半 求调,谢谢
查看原帖
50分 TLE 了一半 求调,谢谢
1049885
zdd6310楼主2024/1/19 21:37

rt

在一半的点 TLE,其他也不是很正常

#include<bits/stdc++.h>
#define R register
using namespace std;
inline void read(int &x){
	char ch;
	while(ch = getchar(), ch < '!'); x = ch - 48;
	while(ch = getchar(), ch > '!') x = (x << 3) + (x << 1) + ch - 48;
}
const int MAXN=1e5+5;
const int inf=1e9;
int n,m,c;
int a[MAXN],b[MAXN];
struct Tree{
    int sum,mx,mn;
    Tree(int sum=0,int mx=-inf,int mn=inf):sum(sum),mx(mx),mn(mn){};
    inline friend Tree operator +(Tree a,Tree b){return Tree(a.sum+b.sum,max(a.mx,b.mx),min(a.mn,b.mn));}
}tr[MAXN<<2];
inline void build(int l,int r,int q){
    if(l==r){
        tr[q]=Tree(a[l],a[l],a[l]);
        return ;
    }
    R int mid=l+r>>1;
    build(l,mid,q*2);
    build(mid+1,r,q*2+1);
    tr[q]=tr[q*2]+tr[q*2+1];
}
inline int query_sum(int l,int r,int ql,int qr,int q){
    if(l==r)return tr[q].sum;
    R int mid=l+r>>1,ans=0;
    if(ql<=mid)ans+=query_sum(l,mid,ql,qr,q*2);
    if(mid<qr)ans+=query_sum(mid+1,r,ql,qr,q*2+1);
    return ans;
}
inline int query_mx(int l,int r,int ql,int qr,int q){
    if(l==r)return tr[q].mx;
    R int mid=l+r>>1,ans=-inf;
    if(ql<=mid)ans=max(ans,query_mx(l,mid,ql,qr,q*2));
    if(mid<qr)ans=max(ans,query_mx(mid+1,r,ql,qr,q*2+1));
    return ans;
}
inline int query_mn(int l,int r,int ql,int qr,int q){
    if(l==r)return tr[q].mn;
    R int mid=l+r>>1,ans=inf;
    if(ql<=mid)ans=min(ans,query_mn(l,mid,ql,qr,q*2));
    if(mid<qr)ans=min(ans,query_mn(mid+1,r,ql,qr,q*2+1));
    return ans;
}
inline void update(int l,int r,int ql,int q,int k){
    if(l==r){
        tr[q]=Tree(k,k,k);
        return ;
    }
    R int mid=l+r>>1;
    if(ql<=mid)update(l,mid,ql,q*2,k);
    else update(mid+1,r,ql,q*2+1,k);
    tr[q]=tr[q*2]+tr[q*2+1];
}
#define iter set<ODT>::iterator
struct ODT{
    int l,r;mutable int v;
    ODT(int l,int r=0,int v=0):l(l),r(r),v(v){};
    inline friend bool operator <(ODT a,ODT b){
        return a.l<b.l;
    }
};
set<ODT>s;
inline iter split(int pos){
    iter it=--s.upper_bound(ODT(pos));
    if(it->l==pos)return it;
    int l=it->l,r=it->r,v=it->v;
    s.erase(it);
    s.insert(ODT(l,pos-1,v));
    return s.insert(ODT(pos,r,v)).first;
}
inline void assign(int l,int r,int x){
    iter ir=split(r+1),il=split(l);
    s.erase(il,ir);
    s.insert(ODT(l,r,x));
}
int cnt[MAXN];
inline int R1(int l,int r){
    if(c==1)return query_mn(1,n,l,r,1);
    memset(cnt,0,sizeof cnt);
    iter ir=split(r+1),il=split(l),i=il;
    int cntt=0,ans=inf,tot=0;
    while(i!=ir){
        if(!cnt[i->v])tot++;cnt[i->v]++;
        while(tot==c){
            cntt=query_sum(1,n,il->r,i->l,1);
            ans=min(ans,cntt);
            cnt[il->v]--;if(!cnt[il->v])tot--;
            il++;
        }
        i++;
    }
    if(ans==inf)return -1;
    return ans;
}
inline int R2(int l,int r){
    memset(cnt,0,sizeof cnt);
    iter ir=split(r+1),il=split(l);
    int cntt=0,ans=query_mx(1,n,l,r,1);
    iter i=il;
    while(i!=ir){
        cnt[i->v]++;
        while(i!=il&&cnt[i->v]>1)cnt[(il++)->v]--;
        if(i!=il){
            cntt=query_sum(1,n,il->r,i->l,1);
            ans=max(ans,cntt);
        }
        if(i->l!=i->r){
            while(i!=il)
                cnt[(il++)->v]--;
        }
        i++;
    }
    return ans;
}
int main(){
    read(n),read(m),read(c);
    for(R int i=1;i<=n;i++)read(a[i]);
    build(1,n,1);
    for(R int i=1;i<=n;i++)read(b[i]);
    int lst=1;
    b[n+1]=-1;
    for(R int i=1;i<=n+1;i++)
        if(b[lst]!=b[i]){
            s.insert(ODT(lst,i-1,b[lst]));
            lst=i;
        }
    for(R int i=1,opt,l,r,x;i<=m;i++){
        read(opt);
        if(opt==1){
            read(l),read(r);
            update(1,n,l,1,r);
        }
        if(opt==2){
            read(l),read(r),read(x);
            assign(l,r,x);
        }
        if(opt==3){
            read(l),read(r);
            printf("%d\n",R1(l,r));
        }
        if(opt==4){
            read(l),read(r);
            printf("%d\n",R2(l,r));
        }
    }
}
2024/1/19 21:37
加载中...