码迷,mamicode.com
首页 > 其他好文 > 详细

sdut2880---Devour Magic(山东省第五届ACM题)

时间:2015-04-16 21:59:46      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define M 300000
#define inf 0x3f3f3f3f
using namespace std;
int maxx,minn;
long long sum;
int r,c,m;
struct T
{
    int left,right,min,max,sum;
    int add,set;
}tree[M];
struct e
{
    int t,l,r;
}ss[111111];

int cmp(e a, e b)
{
    return a.t<b.t;
}

void build(int l,int r,int i)
{
    tree[i].left=l;tree[i].right=r;tree[i].set=-1;
    tree[i].add=tree[i].sum=tree[i].max=tree[i].min=0;
    if(l==r)return;
    int mid=l+(r-l)/2;
    build(l,mid,i<<1);
    build(mid+1,r,i<<1|1);
}

void pushdown(int i)
{
    if(tree[i].left>=tree[i].right)return;
    if(tree[i].set!=-1)
    {
        tree[i<<1].set=tree[i<<1|1].set=tree[i].set;
        tree[i<<1].min=tree[i<<1|1].min=tree[i].set;
        tree[i<<1].max=tree[i<<1|1].max=tree[i].set;
        tree[i<<1].add=tree[i<<1|1].add=0;
        tree[i<<1].sum=(tree[i<<1].right-tree[i<<1].left+1)*tree[i].set;
        tree[i<<1|1].sum=(tree[i<<1|1].right-tree[i<<1|1].left+1)*tree[i].set;
    }
    if(tree[i].add>0)
    {
        int add=tree[i].add;
        tree[i<<1].add+=add;tree[i<<1|1].add+=add;
        tree[i<<1].min+=add;tree[i<<1|1].min+=add;
        tree[i<<1].max+=add;tree[i<<1|1].max+=add;
        tree[i<<1].sum+=add*(tree[i<<1].right-tree[i<<1].left+1);
        tree[i<<1|1].sum+=add*(tree[i<<1|1].right-tree[i<<1|1].left+1);
    }
}

void maintain(int i)
{
    if(tree[i].left>=tree[i].right)return;
    tree[i].max=max(tree[i<<1].max,tree[i<<1|1].max);
    tree[i].min=min(tree[i<<1].min,tree[i<<1|1].min);
    tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
}

void update_add(int l,int r,int val,int i)//区间添加
{
    if(tree[i].left==l&&tree[i].right==r)
    {
        tree[i].add+=val;
        tree[i].max+=val;
        tree[i].min+=val;
        tree[i].sum+=(tree[i].right-tree[i].left+1)*val;
        return;
    }
    pushdown(i);
    tree[i].set=-1;
    tree[i].add=0;
    int mid=tree[i].left+(tree[i].right-tree[i].left)/2;
    if(r<=mid)update_add(l,r,val,i<<1);
    else if(l>mid)update_add(l,r,val,i<<1|1);
    else
    {
        update_add(l,mid,val,i<<1);
        update_add(mid+1,r,val,i<<1|1);
    }
    maintain(i);
}

void update_set(int l,int r,int val,int i)//区间修改
{
   // printf("set\n");
    if(tree[i].left==l&&tree[i].right==r)
    {
        tree[i].set=tree[i].max=tree[i].min=val;
        tree[i].add=0;
        tree[i].sum=(tree[i].right-tree[i].left+1)*val;
        return;
    }
    pushdown(i);
    tree[i].set=-1;
    tree[i].add=0;
    int mid=tree[i].left+(tree[i].right-tree[i].left)/2;
    if(r<=mid)update_set(l,r,val,i<<1);
    else if(l>mid)update_set(l,r,val,i<<1|1);
    else
    {
        update_set(l,mid,val,i<<1);
        update_set(mid+1,r,val,i<<1|1);
    }
    maintain(i);
}

void query(int l,int r,int i)//区间查询
{
    if(tree[i].left==l&&tree[i].right==r)
    {
       sum+=tree[i].sum;
       minn=min(minn,tree[i].min);
       maxx=max(maxx,tree[i].max);
        return;
    }
    pushdown(i);
    tree[i].set=-1;tree[i].add=0;
    int mid=tree[i].left+(tree[i].right-tree[i].left)/2;
    if(r<=mid)query(l,r,i<<1);
    else if(l>mid)query(l,r,i<<1|1);
    else
    {
        query(l,mid,i<<1);
        query(mid+1,r,i<<1|1);
    }
    maintain(i);
}



int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {   long long ssum=0;
        int i,re;
        memset(tree,0,sizeof(tree));
        memset(ss,0,sizeof(ss));
        int op,k=0;

        scanf("%d%d",&re,&op);
        build(1,re,1);
        ss[0].t=0;
        for(i=1;i<=op;i++)
            scanf("%d%d%d",&ss[i].t,&ss[i].l,&ss[i].r);
            sort(ss+1,ss+1+op,cmp);

        for(i=1;i<=op;i++)
        {
            int tr=ss[i].t-ss[i-1].t;
            update_add(1,re,tr,1);

            query(ss[i].l,ss[i].r,1);
            ssum+=sum;
            sum=0;
            update_set(ss[i].l,ss[i].r,0,1);
        }
        printf("%lld\n",ssum);

    }
    return 0;
}




/**************************************
	Problem id	: SDUT OJ 2880
	User name	: rain
	Result		: Wrong Answer
	Take Memory	: 9800K
	Take Time	: 710MS
	Submit Time	: 2015-04-16 17:16:03
**************************************/
re无数然后WA无数就找到一个小错误导致不能AC,add那个地方是所有的都+1,想的很清楚但是就是写错了,蛋疼。

sdut2880---Devour Magic(山东省第五届ACM题)

标签:

原文地址:http://blog.csdn.net/hy1405430407/article/details/45080145

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!