Divide and Conquer study notes

This is an old pit. Divide and Conquer kids really do not how to do (fog

Grilled few questions to LOJ is mainly done on pure partition and the partition of CDQ but point Chen partition dichotomy there are also sub-divide and conquer FFT child (so hard I lost my

 

JOISC2014 Day 3 Scarecrow

After the partition consider maintaining increment above the monotony of the stack, the stack below the monotonically decreasing, and then determine the location of each half of the answer just fine.

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define N 200010
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
struct poi{int x,y;}p[N];
bool cmpx(poi a,poi b){return a.x<b.x;}
bool cmpy(poi a,poi b){return a.y<b.y;}
int stk1[N],stk2[N],n1,n2; ll fin;
void solve(int l,int r)
{
    if(l==r)    return;
    int mid=l+r>>1;
    solve(l,mid); solve(mid+1,r);
    sort(p+l,p+mid+1,cmpx); sort(p+mid+1,p+r+1,cmpx);
    int j=l; n1=n2=0;
    for(int i=mid+1;i<=r;i++)
    {
        while(n2 && p[i].y<p[stk2[n2]].y)    n2--;
        stk2[++n2]=i;
        while(j<=mid && p[j].x<p[i].x)
        {
            while(n1 && p[j].y>p[stk1[n1]].y)    n1--;
            stk1[++n1]=j; j++;
        }
        int lpos=1,rpos=n1,ans=0;
        while(lpos<=rpos)
        {
            int mid=lpos+rpos>>1;
            if(p[stk1[mid]].x>p[stk2[n2-1]].x)
                ans=mid,rpos=mid-1;
            else    lpos=mid+1;
        }
        if(ans)    fin+=n1-ans+1;
    }
}
int main()
{
    int n=read();
    for(int i=1;i<=n;i++)
        p[i].x=read(),p[i].y=read();
    p[0].x=p[0].y=-1; sort(p+1,p+n+1,cmpy);
    solve(1,n); printf("%lld\n",fin);
    return 0;
}
View Code

 

"TJOI / HEOI2016" sequence

DP long so simple

$f[i] = max(f[i],f[j]+1)$

$i>j$ $a[i]>=mx[j]$ $mn[i]>=a[j]$

CDQ three thousand million on a partial ordering

Bare tree like the tree cover more people (cancer!

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define N 100010
#define lowbit(x) (x&-x)
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
struct node{int a,mx,mn,f,id;}a[N];
struct bit
{
    int t[N],n;
    void mfy(int x,int v){while(x<=n) t[x]=max(t[x],v),x+=lowbit(x);}
    int qry(int x){int ans=0; while(x) ans=max(ans,t[x]),x-=lowbit(x); return ans;}
    void del(int x){while(x<=n)    t[x]=0,x+=lowbit(x);}
}b;
bool cmpi(node x,node y){return x.id<y.id;}
bool cmpa(node x,node y){return x.a<y.a;}
bool cmpn(node x,node y){return x.mn<y.mn;}
void solve(int l,int r)
{
    if(l==r)    return; int mid=l+r>>1;
    solve(l,mid);
    sort(a+l,a+mid+1,cmpa); sort(a+mid+1,a+r+1,cmpn);
    int w=l;
    for(int i=mid+1;i<=r;i++)
    {
        while(w<=mid && a[w].a<=a[i].mn)
            b.mfy(a[w].mx,a[w].f),w++;
        a[i].f=max(a[i].f,b.qry(a[i].a)+1);
    }
    for(int i=l;i<w;i++)    b.del(a[i].mx);
    sort(a+mid+1,a+r+1,cmpi);
    solve(mid+1,r);
}
int main()
{
    int n=read(),m=read(); b.n=n;
    for(int i=1;i<=n;i++)    a[i].mn=a[i].mx=a[i].a=read(),a[i].id=i,a[i].f=1;
    for(int i=1;i<=m;i++)
    {
        int x=read(),v=read();
        a[x].mx=max(a[x].mx,v);
        a[x].mn=min(a[x].mn,v);
    }
    solve(1,n); int ans=0;
    for(int i=1;i<=n;i++)    ans=max(ans,a[i].f);
    printf("%d\n",ans);
    return 0;
}
View Code

 

[BZOJ2989] sequence

What appears to have two absolute values ​​can think of it! Manhattan distance!

Simply turn the two-dimensional Euclidean distance is the number of points it!

//Love and Freedom.
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define inf 20021225
#define N 600010
#define nd 250010
#define lowbit(x) (x&-x)
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return f*s;
}
struct bit
{
    int t[N],n;
    void modify(int x,int v){while(x<=n)    t[x]+=v,x+=lowbit(x);}
    int query(int x){int ans=0; while(x) ans+=t[x],x-=lowbit(x); return ans;}
    int ask(int x,int y){return query(y)-query(x-1);}
}b;
struct node{int type,x,y,k,id;}a[N],tmp[N];
bool cmpx(node x,node y){return x.x==y.x?x.type>y.type:x.x<y.x;}
int f[N];
void solve(int l,int r)
{
    if(l==r)    return;
    int mid=l+r>>1,t=0; solve(l,mid);
    for(int i=l;i<=mid;i++)    if(!a[i].type)
        tmp[++t]=a[i];
    for(int i=mid+1;i<=r;i++)    if(a[i].type)
    {
        tmp[++t]=(node){+1,a[i].x-a[i].k,a[i].y,a[i].k,a[i].id};
        tmp[++t]=(node){-1,a[i].x+a[i].k,a[i].y,a[i].k,a[i].id};
    }
    sort(tmp+1,tmp+t+1,cmpx);
    for(int i=1;i<=t;i++)
        if(!tmp[i].type)    b.modify(tmp[i].y,1);
        else    f[tmp[i].id]-=tmp[i].type*b.ask(tmp[i].y-tmp[i].k,tmp[i].y+tmp[i].k);
    for(int i=1;i<=t;i++)    if(!tmp[i].type)
        b.modify(tmp[i].y,-1);
    solve(mid+1,r);
}
int top,v[N],fq; char ch[20];
int main()
{
    int n=read(),q=read(),x,y;
    for(int i=1;i<=n;i++)
        v[i]=read(),a[++top]=(node){0,i+v[i],i-v[i]+nd,0,0};
    for(int i=1;i<=q;i++)
    {
        scanf("%s",ch); x=read(),y=read();
        if(ch[0]=='Q')
            a[++top]=(node){1,x+v[x],x-v[x]+nd,y,++fq};
        else
            v[x]=y,a[++top]=(node){0,x+v[x],x-v[x]+nd,0,0};
    }
    b.n=nd+nd; solve(1,top);
    for(int i=1;i<=fq;i++)
        printf("%d\n",f[i]);
    return 0;
}
View Code

 

Today only wrote 3 questions ... too slow ...

Exam children at night ... tired ...

Guess you like

Origin www.cnblogs.com/hanyuweining/p/11579027.html