社区讨论

求助卡常

P7899 [Ynoi2006] rprmq2参与者 4已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mhjacja3
此快照首次捕获于
2025/11/03 23:19
4 个月前
此快照最后确认于
2025/11/03 23:19
4 个月前
查看原帖
rt,20s20s 大概能跑 1.8×1051.8\times 10^5
C
//when you use vector or deque,pay attention to the size of it.
//by OldDriverTree
#include<bits/stdc++.h>
//#include<atcoder/all>
#define P pair<int,int>
#define midx (lx+rx>>1)
#define midy (ly+ry>>1)
#define ll long long
#define mid (l+r>>1)
char *p1,*p2,buf[1<<25];
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<25,stdin),p1==p2)?0:*p1++)
using namespace std;
//using namespace atcoder;
//using mint=modint998244353;
const int N=2e5+2,B=512;
const ll inf=1e15;
vector<P> C[N];
vector<int> a,b; 
array<int,6> c[N];
ll add[N],d[N],s[N];
ll _0,_1,_2,_3;
int n;

struct custom_hash
{
    static uint64_t splitmix64(uint64_t x) {
        x+=0x9e3779b97f4a7c15;
        x=(x^(x>>30) )*0xbf58476d1ce4e5b9;
        x=(x^(x>>27) )*0x94d049bb133111eb;
        return x^(x>>31);
    }
    size_t operator() (uint64_t x) const {
        static const uint64_t FIXED_RANDOM=chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x+FIXED_RANDOM);
    }
};
int read() {
    int x=0; char c=0; while (!isdigit(c) ) c=gc();
    while (isdigit(c) ) x=x*10+(c&15),c=gc(); return x;
}
namespace SGT
{
    int rt,tot,cnt;
    struct node
    {
        int ls,rs,l,r;
        ll maxv,his,tag,histag;
        void add(ll x,ll y) {
            his=max(his,maxv+y),maxv+=x;
            histag=max(histag,tag+y),tag+=x;
        }
    }T[N<<1];
    
    void pushup(int rt) {
        T[rt].maxv=max(T[T[rt].ls].maxv,T[T[rt].rs].maxv);
        T[rt].his=max(T[T[rt].ls].his,T[T[rt].rs].his);
    }
    void Build(int &rt,int l,int r) {
        rt=++tot,T[rt].l=l,T[rt].r=r,T[rt].tag=0,T[rt].histag=-inf;
        if (l==r) return T[rt].maxv=T[rt].his=s[l],s[l]=0,void();
        Build(T[rt].ls,l,mid),Build(T[rt].rs,mid+1,r),pushup(rt);
    }
    void build(int &rt,int l,int r) {
        if (l==r) return Build(rt,b[l],b[r+1]-1);
        rt=++tot,T[rt].l=b[l],T[rt].r=b[r+1]-1,T[rt].tag=0,T[rt].histag=-inf;
        build(T[rt].ls,l,mid),build(T[rt].rs,mid+1,r),pushup(rt);
    }
    void pushdown(int rt) {
        T[T[rt].ls].add(T[rt].tag,T[rt].histag);
        T[T[rt].rs].add(T[rt].tag,T[rt].histag);
        T[rt].tag=0,T[rt].histag=-inf;
    }
    void change(int rt,int l,int r,int x) {
        if (l<=T[rt].l&&T[rt].r<=r) return T[rt].add(x,-inf); pushdown(rt);
        if (l<=T[T[rt].ls].r) change(T[rt].ls,l,r,x);
        if (T[T[rt].rs].l<=r) change(T[rt].rs,l,r,x); pushup(rt);
    }
    void print(int rt,int l,int r,ll *ans) {
        if (l==r) return ans[l]=T[rt].his-cnt*inf,void();
        pushdown(rt),print(T[rt].ls,l,mid,ans),print(T[rt].rs,mid+1,r,ans);
    }
}
namespace quad
{
    ll w[B][B],T[B*B<<4],tag[B*B<<4];
    void add(int rt,int x) { T[rt]+=x,tag[rt]+=x; }
    void build(int rt,int lx,int rx,int ly,int ry) {
        tag[rt]=0; if (lx==rx&&ly==ry) return T[rt]=w[lx][ly],void();
        if (rx-lx>=ry-ly) build(rt<<1,lx,midx,ly,ry),build(rt<<1|1,midx+1,rx,ly,ry);
        else build(rt<<1,lx,rx,ly,midy),build(rt<<1|1,lx,rx,midy+1,ry);
        T[rt]=max(T[rt<<1],T[rt<<1|1]);
    }
    void solve(int rt,int lx,int rx,int ly,int ry,int x,int y,int id,ll Tag)
    {
        if (rx<x&&ry<y) return _0=max(_0,T[rt]+Tag),add(rt,c[id][2]);
        if (rx<x&&ly>=y) return _1=max(_1,T[rt]+Tag),add(rt,c[id][3]);
        if (lx>=x&&ry<y) return _2=max(_2,T[rt]+Tag),add(rt,c[id][4]);
        if (lx>=x&&ly>=y) return _3=max(_3,T[rt]+Tag),add(rt,c[id][5]);
        Tag+=tag[rt];
        if (rx-lx<4&&ry-ly<4)
        {
            int px=min(rx,x-1),qx=max(lx,x),py=min(ry,y-1),qy=max(ly,y);
            for (int i=lx;i<=px;i++) {
                for (int j=ly;j<=py;j++) _0=max(_0,w[i][j]+Tag),T[rt]=max(T[rt],(w[i][j]+=c[id][2])+tag[rt]);
                for (int j=qy;j<=ry;j++) _1=max(_1,w[i][j]+Tag),T[rt]=max(T[rt],(w[i][j]+=c[id][3])+tag[rt]);
            }
            for (int i=qx;i<=rx;i++) {
                for (int j=ly;j<=py;j++) _2=max(_2,w[i][j]+Tag),T[rt]=max(T[rt],(w[i][j]+=c[id][4])+tag[rt]);
                for (int j=qy;j<=ry;j++) _3=max(_3,w[i][j]+Tag),T[rt]=max(T[rt],(w[i][j]+=c[id][5])+tag[rt]);
            }
            return;
        }
        if (rx-lx>=ry-ly) {
            solve(rt<<1,lx,midx,ly,ry,x,y,id,Tag);
            solve(rt<<1|1,midx+1,rx,ly,ry,x,y,id,Tag);
        }
        else {
            solve(rt<<1,lx,rx,ly,midy,x,y,id,Tag);
            solve(rt<<1|1,lx,rx,midy+1,ry,x,y,id,Tag);
        }
        T[rt]=max(T[rt<<1],T[rt<<1|1])+tag[rt];
        return;
    }
}
void solve(int l,int r)
{
    a.push_back(1),a.push_back(n+1),b.push_back(1),b.push_back(n+1);
    for (int i=l;i<r;i++) a.push_back(c[i][0]),b.push_back(c[i][1]);
    sort(a.begin(),a.end() ),a.erase(unique(a.begin(),a.end() ),a.end() );
    sort(b.begin(),b.end() ),b.erase(unique(b.begin(),b.end() ),b.end() );
    for (int i=0;i+1<a.size();i++)
    {
        for (int j=a[i];j<a[i+1];j++)
        {
            if (j>1) {
                for (auto [pos,x]:C[j]) SGT::change(1,1,pos,x);
                SGT::T[1].add(add[j],-inf); if (j>a[i]) SGT::T[1].add(0,0);
                else SGT::T[1].add(inf,inf),SGT::cnt++;
            }
            else {
                for (int i=n;i;i--) s[i]=s[i+1]+d[i];
                SGT::build(SGT::rt,0,b.size()-2);
            }
        }
        SGT::print(1,0,b.size()-2,quad::w[i]);
    }
    quad::build(1,0,B-1,0,B-1);
    for (int i=l;i<r;i++) {
        int x=lower_bound(a.begin(),a.end(),c[i][0])-a.begin();
        int y=lower_bound(b.begin(),b.end(),c[i][1])-b.begin();
        _0=_1=_2=_3=0,quad::solve(1,0,B-1,0,B-1,x,y,i,0);
        printf("%lld\n%lld\n%lld\n%lld\n",_0,_1,_2,_3);
    }
    for (int i=l;i<r;i++) {
        C[c[i][0] ].push_back({c[i][1]-1,c[i][4]-c[i][2]-c[i][5]+c[i][3]});
        d[c[i][1]-1]+=c[i][2]-c[i][3],d[n]+=c[i][3],add[c[i][0] ]+=c[i][5]-c[i][3];
    }
    a.clear(),b.clear();
    SGT::tot=SGT::cnt=0;
}
main()
{
    n=read();
    for (int i=0;i<n;i++)
        for (int j=0;j<6;j++)
            c[i][j]=read();

    for (int l=0,r;l<n;l+=B-1)
    solve(l,min(l+B-1,n) ); return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...