[12.13] Diary

12.13 Diary

Clever but useless

Analyzing is not a power of 2:? X> 0 (x & (x - 1)) == 0: false

CDQ

  1. P3374: Fenwick tree single point addition and subtraction + range query

When thinking of CDQ can follow the following ideas:

Assumptions about the impact of each zone inside the interior of statistics has been finished, and have been in accordance with the second key (position) sorted up.

Well first of all, because they have (time) sorted according to the first keyword began CDQ, so all the t's on the left less than t on the right, the first dimension is guaranteed.

After then, because the left and right are sorted according to the second keyword, so double-pointer, each taking the smaller one, the following elements must be better than just take away that big (or equal to).

Next, consider the actual meaning, the first dimension of a small section of the left, it is to carry out operations. So obviously, the right to modify the operating range of the interval left meaningless (because no change on the right, the left has been asked over), the impact zone of the left and right to modify the operation of the second interval depends on the keywords, if you modify the left section is smaller than the interrogation position of the operation right, then the impact is, the concrete query is split into two parts, [1, l-1] and [1, r], on inquiry to the first cut, to a second interrogation it is a plus. Note that the answer to be stored off-line operation is in accordance with the order inquiry.

In addition, if pos (second key) how to do the same? Must then sort the third key ! The principle is very simple, the actual meaning is certainly the first statistical changes, ask reprocessing operation, or it will leak.

I just hung in both places.

#include<bits/stdc++.h>
using namespace std;
const int M=5e5+20;
#define mid ((l+r)>>1)
#define LL long long 
struct C{
    int type,pos,val;
    C(int a=0,int b=0,int c=0):type(a),pos(b),val(c){}//若type=1,val=修改数值,若type=2/3,val=询问位置
    bool operator<(C x){
        return pos<x.pos||(pos==x.pos&&type<x.type);
    }
}v[M*3],tmp[M*3];
LL ans[M];
int cnt;
void CDQ(int l,int r){
    if (l==r)
        return;
    CDQ(l,mid),CDQ(mid+1,r);
    int i=l,j=mid+1,k=l;
    LL sum=0;
    while(i<=mid&&j<=r)
        if (v[i]<v[j]){
            if (v[i].type==1)
                sum+=v[i].val;
            tmp[k++]=v[i++];
        }
        else{
            if (v[j].type==2)
                ans[v[j].val]-=sum;
            else if (v[j].type==3)
                ans[v[j].val]+=sum;
            tmp[k++]=v[j++];
        }
    while(i<=mid)
        tmp[k++]=v[i++];
    while(j<=r){
        if (v[j].type==2)
            ans[v[j].val]-=sum;
        else if (v[j].type==3)
            ans[v[j].val]+=sum;
        tmp[k++]=v[j++];
    }
    for(int i=l;i<=r;++i)
        v[i]=tmp[i];
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        int c;
        scanf("%d",&c);
        v[++cnt]=C(1,i,c);
    }
    for(int i=1;i<=m;++i){
        int op,x,y;
        scanf("%d%d%d",&op,&x,&y);
        if (op==1)
            v[++cnt]=C(1,x,y);
        else
            v[++cnt]=C(2,x-1,i),
            v[++cnt]=C(3,y,i);
    }
    CDQ(1,cnt);
    for(int i=1;i<=m;++i)
        if (ans[i])
            printf("%lld\n",ans[i]);
    return 0;
}
  1. P3810: three partial order

Need to go heavy job.

#include<bits/stdc++.h>//还需要去重
using namespace std;
const int M=5e5+20;
#define mid ((l+r)>>1)
struct C{
    int a,b,c,no;
    C(int d=0,int e=0,int f=0,int g=0):a(d),b(e),c(f),no(g){}
    bool operator<(const C &x)const{
        if (a!=x.a)
            return a<x.a;
        else if (b!=x.b)
            return b<x.b;
        return c<x.c;
    }
}v[M],ca[M];
int n,k,c[M*2],ans[M],res[M];
inline int lowbit(int x){return x&(-x);}
inline void operate(int x,int kk){
    for(int i=x;i<=2e5;i+=lowbit(i))
        c[i]+=kk;
}
inline int query(int x){//1-x的和
    int ans=0;
    for(int i=x;i;i-=lowbit(i))
        ans+=c[i];
    return ans;
}
void CDQ(int l,int r){
    if (l==r)
        return;
    CDQ(l,mid),CDQ(mid+1,r);
    int i=l,j=mid+1,kk=l;
    while(i<=mid&&j<=r)
        if(v[i].b<=v[j].b)
            operate(v[i].c,1),
            ca[kk++]=v[i++];
        else
            ans[v[j].no]+=query(v[j].c),
            ca[kk++]=v[j++];
    while(i<=mid)
        operate(v[i].c,1),
        ca[kk++]=v[i++];
    while(j<=r)
        ans[v[j].no]+=query(v[j].c),
        ca[kk++]=v[j++];
    for(int a=l;a<=mid;++a)
        operate(v[a].c,-1);
    for(int a=l;a<=r;++a)
        v[a]=ca[a];
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;++i)
        scanf("%d%d%d",&v[i].a,&v[i].b,&v[i].c),v[i].no=i;
    sort(v+1,v+n+1);
    CDQ(1,n);
    for(int i=1;i<=n;++i)
        ++res[ans[i]];
    for(int i=1;i<=n;++i)
        printf("%d\n",ans[i]);
    for(int i=0;i<n;++i)
        printf("%d\n",res[i]);
    return 0;
}

Two forced balanced tree

CDQ practice:

1 whole half

The answer is-half run cdq,

For inquiries large k, we get the number of left num, if k <= num, go to the left, or k- = num, go to the right

Otherwise k <= mid points left, or farther to the right.

For inquiries rank, we only k> mid time, with num update the answer.

For inquiries precursor, we only k> mid time, with the corresponding section on the left max update answer (segment tree maintenance can be).

(I count all negated by subsequent conversion of the precursor to the process.)

This method is better achieved.

Let U be the number range, the time (n-m +) logUlogn. After discrete should be (the n-+ m) lognlogn, but I'm too lazy discrete. .

At present I took this title Luo Valley rank2.

core part:

void solve(int L,int R,int l,int r)
{
    if (l>r) return;
    if (L==R)
    {
        for (i=l;i<=r;++i)
        {
            x=q[i];
            if (a[x].type==2) ans[a[x].id]=L;
        }
        return;
    }
    int mid=(L+R)>>1;
    t1=t2=t3=0;
    for (i=l;i<=r;++i)
    {
        now=q[i];
        if (a[now].type==2)
        {
            num=T.qiu_s(a[now].l,a[now].r);
            if (num<a[now].x) { a[now].x-=num;q2[++t2]=now; }
            else  q1[++t1]=now; 
        } else
        {
            if (a[now].x>mid) q2[++t2]=now; 
            else  q1[++t1]=now; 

            if (a[now].type==3)
            {
                if (a[now].x<=mid)
                {
                    q3[++t3]=now;
                 T.add(a[now].l,a[now].id,a[now].x);
                }
            } else
            if (a[now].x>mid)
            if (a[now].type==4)
            {
                chmax(ans[a[now].id],T.qiu_m(a[now].l,a[now].r));
            } else
             ans[a[now].id]+=T.qiu_s(a[now].l,a[now].r);
        }
    }

    while (t3) { now=q3[t3--];T.clear(a[now].l); }
    int k=l-1;
    for (i=1;i<=t1;++i) q[++k]=q1[i];
    for (i=1;i<=t2;++i) q[k+i]=q2[i];
    solve(L,mid,l,k);solve(mid+1,R,k+1,r);
}

Guess you like

Origin www.cnblogs.com/diorvh/p/12078795.html
Recommended