Luogu P5103 "JOI 2016 Final" Fenwick tree or fault tree line head +

Too god of this problem. . .


The original ground rises, can operate upside down (back in time), converted to land subsidence, the final answer is the depth of each point.

The following operations are defined as 1,2 settling down (conversion opposite to the original meaning of the title);

First, this problem will only operate ** ** prefixes and suffixes, and only the number (ordinate) becomes small prefix (operation 2), the suffix number (abscissa) is increased (operation 1), the * * ** monotonic, it may be two. (Interpretation of the meaning of the brackets below)

First coordinate rotation entire $ 45 $ degrees (counterclockwise for example), i.e., an operation ordinate $ y> = xi $ points will go to the right $ 2 * l $, abscissa $ + 2 * l $, not ordinate change, due to monotonicity, only operation suffix; 2 operation i.e. the abscissa $ x <= xi $ point will go down $ 2 * l $, ordinate $ -2 * l $, the abscissa unchanged, because monotonic, it will only operate prefix.

So about half of the actual coordinates just fine. . Note that the last calculated depth $ (xy) / 2 $

This dichotomy I need to maintain a maximum of $ mx $ interval, the second time-glance left and right subtrees of $ mx $, then recursively to decide which sub-tree.

#include<cstdio>
#include<iostream>
#define ls (tr<<1)
#define rs (tr<<1|1)
#define ll long long
#define R register ll
const int N=200010,Inf=0x3f3f3f3f;
using namespace std;
char B[1<<15],*S=B,*T=B,ch;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
int n,m;
struct node {int x,d,l;}q[N];
ll MX[2][N<<2],TG[2][N<<2];
#define mx MX[c]
#define tg TG[c]
inline void build(int c,int tr,int l,int r) {
    if(l==r) {mx[tr]=l; return ;} R md=l+r>>1;
    build(c,ls,l,md),build(c,rs,md+1,r); mx[tr]=max(mx[ls],mx[rs]);
}
inline void spread(int c,int tr) { if(!tg[tr]) return ;
    tg[ls]+=tg[tr],tg[rs]+=tg[tr],mx[ls]+=tg[tr],mx[rs]+=tg[tr]; tg[tr]=0;
} ll pos;
inline void fx(int tr,int l,int r,int k) {
    if(l==r) {if(MX[0][tr]<=k) pos=max(pos,(ll)l); return ;} spread(0,tr); R md=l+r>>1;
    if(MX[0][ls]<=k) pos=max(pos,md),fx(rs,md+1,r,k); else fx(ls,l,md,k);
}
inline void fy(int tr,int l,int r,int k) {
    if(l==r) {if(MX[1][tr]>k) pos=min(pos,(ll)l); return ;} spread(1,tr); R md=l+r>>1;
    if(MX[1][ls]<=k) fy(rs,md+1,r,k); else fy(ls,l,md,k);
}
inline void add(int c,int tr,int l,int r,int LL,int RR,int d) {
    if(LL<=l&&r<=RR) {mx[tr]+=d,tg[tr]+=d; return ;} spread(c,tr); R md=l+r>>1;
    if(LL<=md) add(c,ls,l,md,LL,RR,d); if(RR>md) add(c,rs,md+1,r,LL,RR,d); mx[tr]=max(mx[ls],mx[rs]);
} ll p[2][N];
inline void calc(int c,int tr,int l,int r) {
    if(l==r) {p[c][l]=mx[tr]; return ;} spread(c,tr); 
    R md=l+r>>1; calc(c,ls,l,md),calc(c,rs,md+1,r);
}
signed main() { freopen("geologic.in","r",stdin); freopen("geologic.out","w",stdout);
    n=g(),m=g(); for(R i=1;i<=m;++i) q[i].x=g(),q[i].d=g(),q[i].l=g();
    build(0,1,1,n),build(1,1,1,n); for(R i=m;i>=1;--i) { 
        if(q[i].d==1) {
            pos=0; fx(1,1,n,q[i].x);
            if(pos) add(1,1,1,n,1,pos,-2*q[i].l);
        } else {
            pos=Inf; fy(1,1,n,q[i].x);
            if(pos!=Inf) add(0,1,1,n,pos,n,2*q[i].l);
        } //cerr<<pos<<endl;
    } calc(0,1,1,n),calc(1,1,1,n);
    for(R i=1,ans;i<=n;++i) ans=(p[0][i]-p[1][i])/2,printf("%lld\n",ans);
}

It also has a non-rotating coordinate specific direct simulation is similar, but the difficulty in how-half position;

Think found: This is not a linear equation it. . .

Still maintain horizontal and vertical coordinates, respectively, but the conditions are changed to binary $ y> = x-xi $ i.e. $ xy <= xi $ or $ y> = - x + xi $ i.e. $ x + y> = xi $;

#include<cstdio>
#include<iostream>
#define ll long long
#define R register ll
const int M=262145;
char B[1<<15],*S=B,*T=B;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
using namespace std;
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
} ll x[M],y[M],ans[M];
inline int fx(ll d) { R pos=0,t;
    for(R i=17;~i;--i) if((t=x[pos+(1<<i)]-y[pos+(1<<i)])<=d) pos+=(1<<i),d-=t; return pos;
} 
inline int fy(ll d) { R pos=0,t;
    for(R i=17;~i;--i) if((t=x[pos+(1<<i)]+y[pos+(1<<i)])<=d) pos+=(1<<i),d-=t; return pos;
} int n,m;
inline void add(int pos,int incx,int incy) {for(;pos<M;pos+=pos&-pos) x[pos]+=incx,y[pos]+=incy;}
struct node {int x,d,l;} q[M];
signed main() { freopen("geologic.in","r",stdin); freopen("geologic.out","w",stdout);
    n=g(),m=g(); for(R i=1;i<=n;++i) add(i,1,0);
    for(R i=1;i<=m;++i) q[i].x=g(),q[i].d=g(),q[i].l=g();
    for(R i=m;i;--i) if(q[i].d==1) {
        R pos=fx(q[i].x); if(pos) add(1,-q[i].l,-q[i].l),add(pos+1,q[i].l,q[i].l);
    } else { R pos=fy(q[i].x); if(pos<n) add(pos+1,q[i].l,-q[i].l);} 
    for(R i=1;i<=n;++i) {
        ans[i]=ans[i-(i&-i)]+y[i];
        printf("%lld\n",-ans[i]);    
    }
}

 

2019.06.01 June

Guess you like

Origin www.cnblogs.com/Jackpei/p/10959456.html