bzoj4822: [Cqoi2017]老C的任务(扫描线+BIT/线段树)

Posted Sakits

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4822: [Cqoi2017]老C的任务(扫描线+BIT/线段树)相关的知识,希望对你有一定的参考价值。

  裸题...

  依旧是写了BIT和线段树两种(才不是写完线段树后才想起来可以写BIT呢

  怎么卡常数都挺大...QAQ ccz和yy的写法好快哇

BIT:

技术分享
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<map>
#define ll long long 
using namespace std;
const int maxn=500010,inf=1e9;
struct poi{int fir,sec,trd,ty,pos,w;}a[maxn];
int n,m,x,y,z,cnt,N,x1,x2,y1,y2;
int b[maxn];
ll tree[maxn],ans[maxn];
void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<0||c>9)c==-&&(f=-1),c=getchar();
    while(c<=9&&c>=0)k=k*10+c-0,c=getchar();
    k*=f;
}
inline bool cmp(poi a,poi b){return a.fir==b.fir?a.ty<b.ty:a.fir<b.fir;}
inline int lowbit(int x){return x&-x;}
inline void add(int x,int delta){for(;x<=N;x+=lowbit(x))tree[x]+=delta;}
inline ll query(int x){ll sum=0;for(;x;x-=lowbit(x))sum+=tree[x];return sum;}
int main()
{
    read(n);read(m);cnt=n;
    for(int i=1;i<=n;i++)
    {
        read(x);read(y);read(z);
        a[i].fir=x;a[i].sec=y;a[i].w=z;b[++N]=y;
    }
    for(int i=1;i<=m;i++)
    {
        read(x1);read(y1);read(x2);read(y2);
        a[++cnt].fir=x1;a[cnt].sec=y1;a[cnt].trd=y2;a[cnt].ty=-1;a[cnt].pos=i;
        a[++cnt]=a[cnt-1];a[cnt].fir=x2;a[cnt].ty=1;b[++N]=y1;b[++N]=y2;
    }
    sort(b+1,b+1+N);
    for(int i=1;i<=n;i++)a[i].sec=lower_bound(b+1,b+1+N,a[i].sec)-b;
    for(int i=n+1;i<=cnt;i+=2)
    {
        a[i].sec=a[i+1].sec=lower_bound(b+1,b+1+N,a[i].sec)-b;
        a[i].trd=a[i+1].trd=lower_bound(b+1,b+1+N,a[i].trd)-b;
    }
    sort(a+1,a+1+cnt,cmp);
    for(int i=1;i<=cnt;i++)
    {
        if(a[i].ty)
        {
            ll sum=query(a[i].trd)-query(a[i].sec-1);
            ans[a[i].pos]+=(a[i].ty==1?sum:-sum);
        }
        else add(a[i].sec,a[i].w);
    }
    for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
    return 0;
}
View Code

线段树:

技术分享
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<map>
#define ll long long 
using namespace std;
const int maxn=500010,inf=1e9;
struct poi{int fir,sec,trd,ty,pos,w;}a[maxn];
int n,m,x,y,z,cnt,N,x1,x2,y1,y2;
int b[maxn];
ll tree[maxn*4],ans[maxn];
void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<0||c>9)c==-&&(f=-1),c=getchar();
    while(c<=9&&c>=0)k=k*10+c-0,c=getchar();
    k*=f;
}
inline bool cmp(poi a,poi b){return a.fir==b.fir?a.ty<b.ty:a.fir<b.fir;}
inline void pushup(int x){tree[x]=tree[x<<1]+tree[x<<1|1];}
inline void add(int x,int l,int r,int cx,int delta)
{
    if(l==r){tree[x]+=delta;return;}
    int mid=(l+r)>>1;
    if(cx<=mid)add(x<<1,l,mid,cx,delta);
    else add(x<<1|1,mid+1,r,cx,delta);
    pushup(x);
}
inline ll query(int x,int l,int r,int cl,int cr)
{
    if(cl<=l&&r<=cr)return tree[x];
    int mid=(l+r)>>1;ll ret=0;
    if(cl<=mid)ret+=query(x<<1,l,mid,cl,cr);
    if(cr>mid)ret+=query(x<<1|1,mid+1,r,cl,cr);
    return ret;
}
int main()
{
    read(n);read(m);cnt=n;
    for(int i=1;i<=n;i++)
    {
        read(x);read(y);read(z);
        a[i].fir=x;a[i].sec=y;a[i].w=z;b[++N]=y;
    }
    for(int i=1;i<=m;i++)
    {
        read(x1);read(y1);read(x2);read(y2);
        a[++cnt].fir=x1;a[cnt].sec=y1;a[cnt].trd=y2;a[cnt].ty=-1;a[cnt].pos=i;
        a[++cnt]=a[cnt-1];a[cnt].fir=x2;a[cnt].ty=1;b[++N]=y1;b[++N]=y2;
    }
    sort(b+1,b+1+N);
    for(int i=1;i<=n;i++)a[i].sec=lower_bound(b+1,b+1+N,a[i].sec)-b;
    for(int i=n+1;i<=cnt;i+=2)
    {
        a[i].sec=a[i+1].sec=lower_bound(b+1,b+1+N,a[i].sec)-b;
        a[i].trd=a[i+1].trd=lower_bound(b+1,b+1+N,a[i].trd)-b;
    }
    sort(a+1,a+1+cnt,cmp);
    for(int i=1;i<=cnt;i++)
    {
        if(a[i].ty)
        {
            ll sum=query(1,1,N,a[i].sec,a[i].trd);
            ans[a[i].pos]+=(a[i].ty==1?sum:-sum);
        }
        else add(1,1,N,a[i].sec,a[i].w);
    }
    for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
    return 0;
}
View Code

 

以上是关于bzoj4822: [Cqoi2017]老C的任务(扫描线+BIT/线段树)的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ4822][CQOI2017]老C的任务(扫描线+树状数组)

BZOJ 4822: [Cqoi2017]老C的任务

bzoj4822: [Cqoi2017]老C的任务(扫描线+BIT/线段树)

BZOJ1935/4822[Shoi2007]Tree 园丁的烦恼/[Cqoi2017]老C的任务 树状数组

[BZOJ4824][CQOI2017]老C的键盘(树形DP)

BZOJ 4824: [Cqoi2017]老C的键盘