CodeForces 286D

来源:互联网 发布:玻璃排班优化软件 编辑:程序博客网 时间:2024/06/01 18:09

扫描线+线段树
扫描线处理墙壁的交,取最早出现时间
线段树算出每段墙壁对每个时间的贡献
对于[l,r,t]的墙壁
t-l+1以后出现的蚂蚁会完整走完[l,r],[t-l+1,1e9]的答案增加r-l+1

[t-r,t-l]成等差数列,线段树维护下就好

#include<cstdio>#include<cstring>#include<iostream>#include<set>#include<algorithm>using namespace std;const int N=1e5+100;#define mid (l+r)/2int add[N<<6],num[N<<6],lazy[N<<6],ls[N<<6],rs[N<<6],total;int init(){    num[total]=add[total]=lazy[total]=0;    ls[total]=rs[total]=-1;    return total++;}void down(int l,int r,int o){    if(ls[o]==-1)ls[o]=init();    if(rs[o]==-1)rs[o]=init();    int ll=ls[o],rr=rs[o];    add[ll]+=add[o];    add[rr]+=add[o]+num[o]*(mid+1-l);    num[ll]+=num[o];    num[rr]+=num[o];    lazy[ll]+=lazy[o];    lazy[rr]+=lazy[o];    num[o]=add[o]=lazy[o]=0;}int L,R,V,op;void update(int l,int r,int o){    if(L<=l&&r<=R){        if(op==0){            lazy[o]+=V;        }        else {            add[o]+=l-L+1;            num[o]++;        }        return ;    }    down(l,r,o);    int ll=ls[o],rr=rs[o];    if(L<=mid)update(l,mid,ll);    if(R>mid)update(mid+1,r,rr);}int query(int l,int r,int o,int x){    if(l==r){        return add[o]+lazy[o];    }    down(l,r,o);    int ll=ls[o],rr=rs[o];    if(x<=mid)return query(l,mid,ll,x);    else return query(mid+1,r,rr,x);}struct Node {    int l,t,fg;    Node(){}    Node(int l,int t,int fg):l(l),t(t),fg(fg){}    bool operator<(const Node & th)const {        if(l!=th.l)return l<th.l;        if(fg!=th.fg)return fg>th.fg;        return t<th.t;    }}node[N*2];int ll[N*4],rr[N*4],tt[N*4];multiset<int> st;int main(){    #ifdef DouBi    freopen("in.cpp","r",stdin);    #endif // DouBi    int n,m;    while(scanf("%d%d",&n,&m)!=EOF){        int tot=0;        for(int i=0;i<m;i++){            int l,r,t;scanf("%d%d%d",&l,&r,&t);r--;//            if(l>r){//                printf("%d %d %dlr\n",l,r,t);//            }            node[tot++]=Node(l,t,1);            node[tot++]=Node(r,t,-1);        }        sort(node,node+tot);        int cnt=0,pre;        st.clear();        for(int i=0;i<tot;i++){            int l=node[i].l,t=node[i].t,fg=node[i].fg;            //printf("%d %d %d\n",l,t,fg);            if(st.size()==0){                pre=l;                st.insert(t);                continue;            }            if(l>pre){                ll[cnt]=pre;rr[cnt]=l-1;tt[cnt]=*st.begin();                cnt++;                pre=l;            }            if(fg==-1){                if(pre==l){                    ll[cnt]=pre;rr[cnt]=l;tt[cnt]=*st.begin();                    cnt++;                    pre=l+1;                }                //printf("%d %d\n",*st.lower_bound(t),t);                st.erase(st.lower_bound(t));            }            else {                st.insert(t);            }        }//        for(int i=0;i<cnt;i++){//            printf("%d %d %d\n",ll[i],rr[i],tt[i]);//        }        int ed=1e9;        total=0;        init();        for(int i=0;i<cnt;i++){            int l=ll[i],r=rr[i],t=tt[i];            op=0;V=r-l+1;L=max(0,t-l+1),R=ed;            //printf("%d %d\n",L,R);            if(L<=R)update(0,ed,0);            L=t-r,R=t-l;op=1;            //printf("%d %d\n",l,r);            if(R>=0)update(0,ed,0);        }        for(int i=0;i<n;i++){            int a;scanf("%d",&a);            printf("%d\n",query(0,ed,0,a));        }    }    return 0;}
0 0