2018-3-20模拟考试 果冻之王

Posted on 2018-03-28 22:21  SirKnight  阅读(124)  评论(1)    收藏  举报

 

树状数组套线段树,一个维护x一个维护y,要动态开点否则会炸空间。正解是cdq分治,懒得写了就被卡常了。。。

 

#include <stdio.h>
using namespace std;

const int maxn=1e5+1;

struct node
{
    int l,r,lson,rson,sum;
}tree[maxn*100];//权值线段树 

int n,s[maxn][3],rt[maxn];
int top=0,cnt=0,summ;

int read()
{
    char ch=getchar();
    int flag=1,x=0;
    while((ch<'0'||ch>'9')&&ch!='-')
        ch=getchar();
    if(ch=='-')
    {
        flag=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*flag;
}

int lowbit(int x)
{
    return x&(-x);
}

void pushup(int x)
{
    tree[x].sum=tree[tree[x].lson].sum+tree[tree[x].rson].sum;//要存一个lson和rson 
}

void add(int &x,int k,int lt,int rt,int z)//动态开点 
{
    if(!x)
        x=++cnt;
    tree[x].l=lt,tree[x].r=rt;
    if(lt==rt)
    {
        tree[x].sum+=z;
        return;
    }
    int mid=(lt+rt)/2;
    if(mid>=k)    
        add(tree[x].lson,k,lt,mid,z);
    else
        add(tree[x].rson,k,mid+1,rt,z);
    pushup(x);
}

void insert(int x,int y,int z)
{
    while(x<=100000)//最大值 
    {
        add(rt[x],y,1,1e5,z);
        x+=lowbit(x);
    }
}

int query1(int x)
{
    int sum=0;
    while(x>=1)
    {
        sum+=tree[rt[x]].sum;
        x-=lowbit(x);
    }
    return sum;
}

int query22(int x,int y)
{
    if(!x)
        return 0;
    int mid=(tree[x].l+tree[x].r)/2;
    if(mid>=y)
        return query22(tree[x].lson,y)+tree[tree[x].rson].sum;
    else
        return query22(tree[x].rson,y);
}

int query2(int x,int y)
{
    int sum=0;
    while(x>=1)
    {
        sum+=query22(rt[x],y);
        x-=lowbit(x);
    }
    return sum;
}

void query4(int x,int lt,int rt)
{
    if(!x)
        return;
    if(tree[x].l>rt||tree[x].r<lt)
        return;
    if(tree[x].l>=lt&&tree[x].r<=rt)
    {
        summ+=tree[x].sum;
        return;
    }
    int mid=(tree[x].l+tree[x].r)/2;
    if(mid>=lt)
        query4(tree[x].lson,lt,rt);
    if(mid<rt)
        query4(tree[x].rson,lt,rt); 
}

int query3(int x,int b,int c)
{
    int sum=0;
    while(x>=1)
    {
        summ=0;
        query4(rt[x],b,c);
        sum+=summ;
        x-=lowbit(x);
    }
    return sum;
}

int main()
{
    n=read();
    int i;
    for(i=1;i<=n;i++)
    {
        int opr;
        opr=read();
        if(opr==1)
        {
            int x,y,z;
            x=read(),y=read(),z=read();
            s[++top][0]=x,s[top][1]=y,s[top][2]=z;
            insert(x,y,z);
        }
        if(opr==2)
        {
            insert(s[top][0],s[top][1],-s[top][2]);
            top--;
        }
        if(opr==3)
        {
            int x;
            x=read();
            printf("%d\n",query1(100000)-query1(x));
        }
        if(opr==4)
        {
            int y;
            y=read();
            printf("%d\n",query2(100000,y));
        }
        if(opr==5)
        {
            int x,y,b,c;
            x=read(),y=read(),b=read(),c=read();
            printf("%d\n",query3(y,b,c)-query3(x-1,b,c));
        } 
    }
    return 0;
}