块状数组(hdu3207 Highway)

来源:互联网 发布:linux创建新用户和组 编辑:程序博客网 时间:2024/06/01 08:47

Highway

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 459    Accepted Submission(s): 65


Problem Description
As we all know, every day, there are hundreds of trucks passing through the highway. As some of the trucks might carry several tons of goods, the highway will be damaged unless it is frequently repaired. The administration of highway is worried about this, so it invented repairing cars to ensure that the cars can pass through the highway.

The highway has an initial durability. If a truck with x tons’ goods pass the highway, its durability will be decreased by x. Once the highway’s durability is less or equal to zero, it will be broken and can never be repaired. The trucks can’t pass through the broken ones.

There are two kinds of repairing cars: T1 can increase the highway’s durability by r, T2 can increase the highway’s durability to p, if the highway’s durability is less than p. Although the repairing cars can pass through the broken parts, the broken parts can’t be repaired.
 

Input
The input consists of several test cases.

For every test case, there are three integers N (1<=N<=100000), M (1<=M<=100000), I (1<=I<=1000) in the first line, indicating the highway’s length, the numbers of cars and the initial durability of the highway.

Each of the next M lines described the information of cars in the following format:
1 s t d -- There is a truck with d tons’ goods wanted to pass the interval [s, t]. You should check whether the truck can pass it. Notice that if the truck can't pass the whole interval, it will give up the whole passing; otherwise it can pass the highway freely, even if the highway will be broken after the truck’s passing.
2 s t r -- A T1 car will pass the interval [s, t] and increase its durability by r.
3 s t p -- A T2 car will pass the interval [s, t] and increase its durability to p.
You can assume that 1<=s<=t<=N, 1<=d, p, r<=1000

The input ends with N=M=I=0.
 

Output
For each case, you should return how many trucks can successfully pass the interval.
 

Sample Input
5 5 51 1 3 32 2 3 101 1 3 31 1 3 11 2 3 15 3 101 1 2 51 2 3 51 1 3 50 0 0
 

Sample Output
32
Hint
In the second test case, the third truck can’t pass the road, because although the durability of interval [1, 2) and (2, 3] is larger than 0, in position 2, the durability is 0.
 

Source
2009 Shanghai Invitation Contest Host by DHU
 


题目大意:

不超过10 ^ 5个数, 一开始设定为相同的正整数, 模拟3种操作:

a) 询问一段区间是否连续, 是的话把这一段数减去某个数, 当某个数小于等于0时相当于断开.

b) 把一段区间的数增加一个数, 断开的数不再增加.

c) 把一段区间的数与某个数取max , 断开的数不参与此过程.

块状数组是一个非常有趣的数据结构,利用分块的思想将再简单不过的数组化腐朽为神奇,sqrt(n)虽不及log(n),

但是性价比还是很好的。

但是需要注意的是块状数组一定要从0开始,这样可以求出i在哪个块中 pos = i / s , 其中s 为一个块的规模。 

块状数组就是将数组以sqrt(size)为单位分割成块,对于每一块单独维护其相应的信息。

www.cnblogs.com/sweetsc/archive/2012/08/15/2639395.html

对块状链表的研究


#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=350;const int maxm=100010;const int INF=1000000000;int N,M,I;struct Block{    int minv[maxn],add[maxn],sub[maxn],a[maxm],setv[maxn];    bool flag[maxn];    bool flag1[maxm];    int sz[maxn];    int size;    void build()    {        size=sqrt(N);        int t=(N-1)/size+1;        for(int i=0;i<t;i++)        {            minv[i]=INF;            setv[i]=-INF;            add[i]=sub[i]=sz[i]=0;            flag[i]=0;        }        int x;        for(int i=0;i<N;i++)        {            a[i]=I;            flag1[i]=0;            x=i/size;            minv[x]=min(a[i],minv[x]);            sz[x]++;        }    }    void pushdown(int s)    {        int lb=size*s,rb=lb+sz[s];        for(int i=lb;i<rb;i++)            if(a[i]+sub[s]<=0)flag1[i]=true;        if(add[s])        {            for(int i=lb;i<rb;i++)                a[i]+=add[s];            add[s]=0;        }        if(setv[s]!=-INF)        {            for(int i=lb;i<rb;i++)                a[i]=max(a[i],setv[s]);            setv[s]=-INF;        }        sub[s]=0;    }    void maintain(int pos)    {        int lb=pos*size,rb=lb+sz[pos];        minv[pos]=INF;        for(int i=lb;i<rb;i++)        {            if(a[i]<=0)flag1[i]=1;            minv[pos]=min(minv[pos],a[i]);        }        if(minv[pos]<=0)flag[pos]=1;    }    void update(int s,int t,int x)    {        int x_pos=s/size,y_pos=t/size;        if(x_pos==y_pos)        {            pushdown(x_pos);            for(int i=s;i<=t;i++)a[i]+=x;            maintain(x_pos);        }        else        {            int lb=s,rb=x_pos*size+sz[x_pos];            pushdown(x_pos);            for(int i=lb;i<rb;i++)a[i]+=x;            maintain(x_pos);            lb=y_pos*size,rb=t+1,            pushdown(y_pos);            for(int i=lb;i<rb;i++)a[i]+=x;            maintain(y_pos);            for(int i=x_pos+1;i<y_pos;i++)            {                add[i]+=x,minv[i]+=x;                if(minv[i]<=0)flag[i]=true,sub[i]=min(sub[i],add[i]);;                if(setv[i]!=-INF)setv[i]+=x;            }        }    }    void update1(int s,int t,int x)    {        int x_pos=s/size,y_pos=t/size;        if(x_pos==y_pos)        {            pushdown(x_pos);            for(int i=s;i<=t;i++)a[i]=max(a[i],x);            maintain(x_pos);        }        else        {            int lb=s,rb=x_pos*size+sz[x_pos];            pushdown(x_pos);            for(int i=lb;i<rb;i++)a[i]=max(a[i],x);            maintain(x_pos);            lb=y_pos*size,rb=t+1,            pushdown(y_pos);            for(int i=lb;i<rb;i++)a[i]=max(a[i],x);            maintain(y_pos);            for(int i=x_pos+1;i<y_pos;i++)            {                setv[i]=max(setv[i],x);                minv[i]=max(minv[i],x);            }        }    }    bool query(int s,int t)    {        int x_pos=s/size,y_pos=t/size;        if(x_pos==y_pos)        {            pushdown(x_pos);            for(int i=s;i<=t;i++)                if(flag1[i])return false;        }        else        {            int lb=s,rb=x_pos*size+sz[x_pos];            pushdown(x_pos);            for(int i=lb;i<rb;i++)                if(flag1[i])return false;            lb=y_pos*size,rb=t+1;            pushdown(y_pos);            for(int i=lb;i<rb;i++)                if(flag1[i])return false;            for(int i=x_pos+1;i<y_pos;i++)                if(flag[i])return false;        }        return true;    }}tree;int main(){    int op,s,t,p;    while(scanf("%d%d%d",&N,&M,&I)!=EOF,N+M+I)    {        tree.build();        int cnt=0;        while(M--)        {            scanf("%d%d%d%d",&op,&s,&t,&p);            s--,t--;            if(op==1)            {                if(tree.query(s,t))                {                    cnt++;                    tree.update(s,t,-p);                }            }            else if(op==2)tree.update(s,t,p);            else tree.update1(s,t,p);        }        printf("%d\n",cnt);    }    return 0;}



0 0
原创粉丝点击