LOJ number of columns block the entry series

table of Contents

1. Interval + plus single enumeration
of each block maintains tag, scattered violent change.
code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=50010;
const int maxt=250;
int n,t,cnt;
int a[maxn],tag[maxt],L[maxt],R[maxt],pos[maxn];
inline void add(int ql,int qr,int k)
{
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)a[i]+=k;
        return;
    }
    for(int i=ql;i<=R[pos[ql]];i++)a[i]+=k;
    for(int i=L[pos[qr]];i<=qr;i++)a[i]+=k;
    if(pos[ql]+1<=pos[qr]-1)for(int i=pos[ql]+1;i<=pos[qr]-1;i++)tag[i]+=k;
}
int main()
{
    scanf("%d",&n);
    t=sqrt(n);cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        int op,x,y,k;
        scanf("%d%d%d%d",&op,&x,&y,&k);
        if(!op)add(x,y,k);
        else printf("%d\n",a[y]+tag[pos[y]]);
    }
    return 0;
}

2. The range of plus + query interval is less than the number of values of a number
of these problems are similar.
code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=50010;
const int maxt=250;
int n,t,cnt;
int a[maxn],b[maxn],L[maxt],R[maxt],pos[maxn],tag[maxt];
inline void add(int ql,int qr,int k)
{
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)a[i]+=k;
        for(int i=L[pos[ql]];i<=R[pos[qr]];i++)b[i]=a[i];
        sort(b+L[pos[ql]],b+R[pos[qr]]+1);
        return;
    }
    for(int i=ql;i<=R[pos[ql]];i++)a[i]+=k;
    for(int i=L[pos[ql]];i<=R[pos[ql]];i++)b[i]=a[i];
    sort(b+L[pos[ql]],b+R[pos[ql]]+1);
    for(int i=L[pos[qr]];i<=qr;i++)a[i]+=k;
    for(int i=L[pos[qr]];i<=R[pos[qr]];i++)b[i]=a[i];
    sort(b+L[pos[qr]],b+R[pos[qr]]+1);
    if(pos[ql]+1<=pos[qr]-1)for(int i=pos[ql]+1;i<=pos[qr]-1;i++)tag[i]+=k;
}
inline int query(int ql,int qr,int k)
{
    int res=0;
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)if(a[i]+tag[pos[ql]]<k)res++;
        return res;
    }
    for(int i=ql;i<=R[pos[ql]];i++)if(a[i]+tag[pos[ql]]<k)res++;
    for(int i=L[pos[qr]];i<=qr;i++)if(a[i]+tag[pos[qr]]<k)res++;
    if(pos[ql]+1<=pos[qr]-1)
        for(int i=pos[ql]+1;i<=pos[qr]-1;i++)
        {
            int l=L[i],r=R[i],ans=0;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(b[mid]+tag[i]<k)l=mid+1,ans=mid-L[i]+1;
                else r=mid-1;
            }
            res+=ans;
        }
    return res;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
    t=sqrt(n);cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    for(int i=1;i<=cnt;i++)sort(b+L[i],b+R[i]+1);
    for(int i=1;i<=n;i++)
    {
        int op,l,r,k;scanf("%d%d%d%d",&op,&l,&r,&k);
        if(!op)add(l,r,k);
        else printf("%d\n",query(l,r,k*k));
    }
    return 0;
}

Interval search section 3. Add + precursor
when put multiset within each block, query lower_bound
code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
const int maxt=350;
int n,t,cnt;
int a[maxn],L[maxt],R[maxt],pos[maxn],tag[maxt];
multiset<int>s[maxt];
inline void add(int ql,int qr,int k)
{
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)s[pos[ql]].erase(s[pos[ql]].find(a[i]));
        for(int i=ql;i<=qr;i++)a[i]+=k;
        for(int i=ql;i<=qr;i++)s[pos[ql]].insert(a[i]);
        return;
    }
    for(int i=ql;i<=R[pos[ql]];i++)s[pos[ql]].erase(s[pos[ql]].find(a[i]));
    for(int i=ql;i<=R[pos[ql]];i++)a[i]+=k;
    for(int i=ql;i<=R[pos[ql]];i++)s[pos[ql]].insert(a[i]);
    for(int i=L[pos[qr]];i<=qr;i++)s[pos[qr]].erase(s[pos[qr]].find(a[i]));
    for(int i=L[pos[qr]];i<=qr;i++)a[i]+=k;
    for(int i=L[pos[qr]];i<=qr;i++)s[pos[qr]].insert(a[i]);
    if(pos[ql]+1<=pos[qr]-1)for(int i=pos[ql]+1;i<=pos[qr]-1;i++)tag[i]+=k;
}
inline int query(int ql,int qr,int k)
{
    int res=-1;
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)if(a[i]+tag[pos[ql]]<k)res=max(res,a[i]+tag[pos[ql]]);
        return res;
    }
    for(int i=ql;i<=R[pos[ql]];i++)if(a[i]+tag[pos[ql]]<k)res=max(res,a[i]+tag[pos[ql]]);
    for(int i=L[pos[qr]];i<=qr;i++)if(a[i]+tag[pos[qr]]<k)res=max(res,a[i]+tag[pos[qr]]);
    if(pos[ql]+1<=pos[qr]-1)
        for(int i=pos[ql]+1;i<=pos[qr]-1;i++)
        {
            set<int>::iterator it=s[i].lower_bound(k-tag[i]);
            if(it==s[i].begin())continue;
            it--;
            res=max(res,*it+tag[i]);
        }
    return res;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    t=sqrt(n),cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    for(int i=1;i<=n;i++)s[pos[i]].insert(a[i]);
    for(int i=1;i<=n;i++)
    {
        int op,l,r,k;scanf("%d%d%d%d",&op,&l,&r,&k);
        if(!op)add(l,r,k);
        else printf("%d\n",query(l,r,k));
    }
    return 0;
}

4. Add Interval Interval + and
the like marking segment tree block.
code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=50010;
const int maxt=250;
int n,t,cnt;
int a[maxn],L[maxt],R[maxt],pos[maxn],sum[maxt],tag[maxt];
inline void add(int ql,int qr,int k)
{
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)a[i]+=k;
        sum[pos[ql]]+=(qr-ql+1)*k;
        return;
    }
    for(int i=ql;i<=R[pos[ql]];i++)a[i]+=k;
    sum[pos[ql]]+=(R[pos[ql]]-ql+1)*k;
    for(int i=L[pos[qr]];i<=qr;i++)a[i]+=k;
    sum[pos[qr]]+=(qr-L[pos[qr]]+1)*k;
    if(pos[ql]+1<=pos[qr]-1)for(int i=pos[ql]+1;i<=pos[qr]-1;i++)tag[i]+=k;
}
inline int query(int ql,int qr,int mod)
{
    int res=0;
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)res=(res+(a[i]+tag[pos[ql]])%mod)%mod;
        return res;
    }
    for(int i=ql;i<=R[pos[ql]];i++)res=(res+(a[i]+tag[pos[ql]])%mod)%mod;
    for(int i=L[pos[qr]];i<=qr;i++)res=(res+(a[i]+tag[pos[qr]])%mod)%mod;
    if(pos[ql]+1<=pos[qr]-1)
        for(int i=pos[ql]+1;i<=pos[qr]-1;i++)res=(res+(sum[i]+(R[i]-L[i]+1)*tag[i]%mod)%mod)%mod;
    return res;
}
signed main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    t=sqrt(n),cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    for(int i=1;i<=n;i++)sum[pos[i]]+=a[i];
    for(int i=1;i<=n;i++)
    {
        int op,l,r,k;scanf("%lld%lld%lld%lld",&op,&l,&r,&k);
        if(!op)add(l,r,k);
        else printf("%lld\n",query(l,r,k+1));
    }
    return 0;
}

5. Interval + square root section and
recording the maximum, the maximum value of 1 or less is not found modified.
code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=50010;
const int maxt=250;
int n,t,cnt;
int a[maxn],L[maxt],R[maxt],pos[maxn],sum[maxt],maxx[maxt];
inline void change(int ql,int qr)
{
    if(pos[ql]==pos[qr])
    {
        if(maxx[pos[ql]]<=1)return;
        for(int i=ql;i<=qr;i++)sum[pos[ql]]-=a[i],a[i]=sqrt(a[i]),sum[pos[ql]]+=a[i];
        maxx[pos[ql]]=0;
        for(int i=L[pos[ql]];i<=R[pos[ql]];i++)maxx[pos[ql]]=max(maxx[pos[ql]],a[i]);
        return;
    }
    if(maxx[pos[ql]]>1)for(int i=ql;i<=R[pos[ql]];i++)sum[pos[ql]]-=a[i],a[i]=sqrt(a[i]),sum[pos[ql]]+=a[i];
    if(maxx[pos[qr]]>1)for(int i=L[pos[qr]];i<=qr;i++)sum[pos[qr]]-=a[i],a[i]=sqrt(a[i]),sum[pos[qr]]+=a[i];
    if(pos[ql]+1>pos[qr]-1)return;
    for(int i=pos[ql]+1;i<=pos[qr]-1;i++)
    {
        if(maxx[i]<=1)continue;
        sum[i]=maxx[i]=0;
        for(int j=L[i];j<=R[i];j++)a[j]=sqrt(a[j]),sum[i]+=a[j];
        for(int j=L[i];j<=R[i];j++)maxx[i]=max(maxx[i],a[j]);
    }   
}
inline int query(int ql,int qr)
{
    int res=0;
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)res+=a[i];
        return res;
    }
    for(int i=ql;i<=R[pos[ql]];i++)res+=a[i];
    for(int i=L[pos[qr]];i<=qr;i++)res+=a[i];
    if(pos[ql]+1<=pos[qr]-1)
        for(int i=pos[ql]+1;i<=pos[qr]-1;i++)res+=sum[i];
    return res;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    t=sqrt(n),cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    for(int i=1;i<=n;i++)sum[pos[i]]+=a[i],maxx[pos[i]]=max(maxx[pos[i]],a[i]);
    for(int i=1;i<=n;i++)
    {
        int op,l,r,k;scanf("%d%d%d%d",&op,&l,&r,&k);
        if(!op)change(l,r);
        else printf("%d\n",query(l,r));
    }
    return 0;
}

6. Insert a k-number + the number of check
insertion to long reconstruction times reaches block, jump inquiry violence.
code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
const int maxt=500;
int n,t,cnt,tot,num;
int a[maxn],c[maxn];
vector<int>ve[maxt];
inline void rebuild()
{
    num=tot=0;
    for(int i=1;i<=cnt;i++)
    {
        for(unsigned int j=0;j<ve[i].size();j++)a[++tot]=ve[i][j];
        ve[i].clear();
    }
    t=sqrt(tot);cnt=tot/t;
    if(tot%t)cnt++;
    for(int i=1;i<=tot;i++)ve[(i-1)/t+1].push_back(a[i]);
}
inline int find(int x)
{
    int now=1;
    while(x>ve[now].size())x-=ve[now].size(),now++;
    return ve[now][x-1];
}
inline void insert(int x,int k)
{
    num++;
    int now=1;
    while(x>ve[now].size())x-=ve[now].size(),now++;
    ve[now].insert(ve[now].begin()+x-1,k);
    if(num==t)rebuild();
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    t=sqrt(n);cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=n;i++)ve[(i-1)/t+1].push_back(a[i]);
    for(int i=1;i<=n;i++)
    {
        int op,l,r,k;scanf("%d%d%d%d",&op,&l,&r,&k);
        if(!op)insert(l,r);
        else printf("%d\n",find(r));
    }
    return 0;
}

7. interval by interval plus + + single enumeration
image segment tree 2 as a marker to maintain
code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
const int maxt=350;
const int mod=10007;
int n,t,cnt;
int a[maxn],pos[maxn],L[maxt],R[maxt],tag1[maxt],tag2[maxt];
inline void down(int x)
{
    for(int i=L[x];i<=R[x];i++)a[i]=(a[i]*tag2[x]%mod+tag1[x])%mod;
    tag1[x]=0,tag2[x]=1;
}
inline void add(int ql,int qr,int k)
{
    if(pos[ql]==pos[qr])
    {
        down(pos[ql]);
        for(int i=ql;i<=qr;i++)a[i]=(a[i]+k)%mod;
        return;
    }
    down(pos[ql]);
    for(int i=ql;i<=R[pos[ql]];i++)a[i]=(a[i]+k)%mod;
    down(pos[qr]);
    for(int i=L[pos[qr]];i<=qr;i++)a[i]=(a[i]+k)%mod;
    if(pos[ql]+1<=pos[qr]-1)for(int i=pos[ql]+1;i<=pos[qr]-1;i++)tag1[i]=(tag1[i]+k)%mod;
}
inline void mul(int ql,int qr,int k)
{
    if(pos[ql]==pos[qr])
    {
        down(pos[ql]);
        for(int i=ql;i<=qr;i++)a[i]=a[i]*k%mod;
        return;
    }
    down(pos[ql]);
    for(int i=ql;i<=R[pos[ql]];i++)a[i]=a[i]*k%mod;
    down(pos[qr]);
    for(int i=L[pos[qr]];i<=qr;i++)a[i]=a[i]*k%mod;
    if(pos[ql]+1<=pos[qr]-1)
        for(int i=pos[ql]+1;i<=pos[qr]-1;i++)
            tag1[i]=tag1[i]*k%mod,tag2[i]=tag2[i]*k%mod;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    t=sqrt(n),cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    for(int i=1;i<=cnt;i++)tag2[i]=1;
    for(int i=1;i<=n;i++)
    {
        int op,l,r,k;scanf("%d%d%d%d",&op,&l,&r,&k);
        if(!op)add(l,r,k);
        if(op==1)mul(l,r,k);
        if(op==2)printf("%d\n",(a[r]*tag2[pos[r]]%mod+tag1[pos[r]])%mod);
    }
    return 0;
}

8. Each time a query interval equal to the number of a value interval and the number assigned to this value
clearly potential, maintaining covered and whether each block is covered by color, two discrete pieces each reconstructed
code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
const int maxt=350;
int n,t,cnt;
int a[maxn],pos[maxn],L[maxt],R[maxt],col[maxt];
inline void down(int x)
{
    if(col[x]==-1)return;
    for(int i=L[x];i<=R[x];i++)a[i]=col[x];
}
inline void reset(int x,int k)
{
    col[x]=k;
    for(int i=L[x];i<=R[x];i++)if(a[i]!=k)col[x]=-1;
}
inline int query(int ql,int qr,int k)
{
    int res=0;
    if(pos[ql]==pos[qr])
    {
        if(~col[pos[ql]])return (col[pos[ql]]==k)?qr-ql+1:0;
        for(int i=ql;i<=qr;i++)res+=(a[i]==k);
        return res;
    }
    if(~col[pos[ql]])res+=(col[pos[ql]]==k)?R[pos[ql]]-ql+1:0;
    else for(int i=ql;i<=R[pos[ql]];i++)res+=(a[i]==k);
    if(~col[pos[qr]])res+=(col[pos[qr]]==k)?qr-L[pos[qr]]+1:0;
    else for(int i=L[pos[qr]];i<=qr;i++)res+=(a[i]==k);
    if(pos[ql]+1<=pos[qr]-1)
        for(int i=pos[ql]+1;i<=pos[qr]-1;i++)
        {
            if(~col[i]){res+=(col[i]==k)?R[i]-L[i]+1:0;continue;}
            for(int j=L[i];j<=R[i];j++)res+=(a[j]==k);
        }   
    return res;
}
inline void change(int ql,int qr,int k)
{
    if(pos[ql]==pos[qr])
    {
        down(pos[ql]);
        for(int i=ql;i<=qr;i++)a[i]=k;
        reset(pos[ql],k);
        return;
    }
    down(pos[ql]);
    for(int i=ql;i<=R[pos[ql]];i++)a[i]=k;
    reset(pos[ql],k);
    down(pos[qr]);
    for(int i=L[pos[qr]];i<=qr;i++)a[i]=k;
    reset(pos[qr],k);
    if(pos[ql]+1<=pos[qr]-1)for(int i=pos[ql]+1;i<=pos[qr]-1;i++)col[i]=k;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    t=sqrt(n),cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    for(int i=1;i<=cnt;i++)col[i]=-1;
    for(int i=1;i<=n;i++)
    {
        int l,r,k;scanf("%d%d%d",&l,&r,&k);
        printf("%d\n",query(l,r,k));
        change(l,r,k);
    }
    return 0;
}

9. The minimum number of public intervals
with this problem the same.

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;
const int maxt=10100;
const int inf=1e9;
int n,t,cnt,num;
int a[maxn],b[maxn],c[maxn],L[maxt],R[maxt],pos[maxn];
int ans[maxt][maxt];
vector<int>ve[maxn];
inline int read()
{
    char c=getchar();int res=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
    return res*f;
}
inline void pre_work()
{
    sort(b+1,b+n+1);num=unique(b+1,b+n+1)-(b+1);b[0]=inf;
    for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+num+1,a[i])-b;
    for(int i=1;i<=n;i++)ve[a[i]].push_back(i);
    for(int i=1;i<=cnt;i++)
    {
        int maxx=0,res=0;
        for(int j=L[i];j<=n;j++)
        {
            c[a[j]]++;
            if(c[a[j]]>maxx||(c[a[j]]==maxx&&b[a[j]]<b[res]))res=a[j],maxx=c[a[j]];
            if(j%t==0||j==n)ans[i][pos[j]]=res;
        }
        for(int j=L[i];j<=n;j++)c[a[j]]--;
    }
}
inline int calc(int ql,int qr,int k)
{
    return upper_bound(ve[k].begin(),ve[k].end(),qr)-lower_bound(ve[k].begin(),ve[k].end(),ql);
}
inline int query(int ql,int qr)
{
    int maxx=0,res=0;
    if(pos[ql]==pos[qr])
    {
        for(int i=ql;i<=qr;i++)
        {
            int tmp=calc(ql,qr,a[i]);
            if(tmp>maxx||(tmp==maxx&&b[a[i]]<b[res]))maxx=tmp,res=a[i];
        }
        return res;
    }
    for(int i=ql;i<=R[pos[ql]];i++)
    {
        int tmp=calc(ql,qr,a[i]);
        if(tmp>maxx||(tmp==maxx&&b[a[i]]<b[res]))maxx=tmp,res=a[i];
    }
    for(int i=L[pos[qr]];i<=qr;i++)
    {
        int tmp=calc(ql,qr,a[i]);
        if(tmp>maxx||(tmp==maxx&&b[a[i]]<b[res]))maxx=tmp,res=a[i];
    }
    int p1=pos[ql]+1,p2=pos[qr]-1;
    if(p1<=p2)
    {
        int tmp=calc(ql,qr,ans[p1][p2]);
        if(tmp>maxx||(tmp==maxx&&b[ans[p1][p2]]<b[res]))maxx=tmp,res=ans[p1][p2];
    }
    return res;
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)a[i]=b[i]=read();
    t=30;cnt=n/t;
    if(n%t)cnt++;
    for(int i=1;i<=cnt;i++)L[i]=(i-1)*t+1,R[i]=min(i*t,n);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
    pre_work();
    for(int i=1;i<=n;i++)
    {
        int l=read(),r=read();
        printf("%d\n",b[query(l,r)]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/nofind/p/11961288.html