• [POI2011]MET-Meteors 整体二分_树状数组_卡常


    线段树肯定会 TLE 的,必须要用树状数组.

    Code:

    // luogu-judger-enable-o2
    #include <cstdio>
    #include <algorithm>
    #include <vector> 
    #include <cstring>
    #include <cctype>
    #define setIO(s) freopen(s".in","r",stdin)
    #define maxn 300009
    #define ll long long
    using namespace std;
    vector<int>G[maxn]; 
    int n,m,k,cnt[maxn],left[maxn<<1],right[maxn<<1],que[maxn],result[maxn]; 
    int tl[maxn],tr[maxn]; 
    int current[maxn],cost[maxn],w[maxn<<1]; 
    inline int read()
    {
        int k=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-')f=-1;
        for(;isdigit(c);c=getchar()) k=k*10+c-'0';return f*k; 
    }
    struct Segment_Tree{
        ll sumv[maxn<<2],lazy[maxn<<2];
        #define lson (o<<1)
        #define rson (o<<1)|1
        void mark(int l,int r,int o,int delta)
        {
            sumv[o]+=delta*(r-l+1);
            lazy[o]+=delta;
        }
        int lowbit(int x){ return x&(-x); }
        void update(int l,int r,int L,int R,int o,int k){
            while(L<=r) sumv[L]+=k,L+=lowbit(L);
            ++R;
            while(R<=r) sumv[R]-=k,R+=lowbit(R); 
        }
        ll query(int l,int r,int pos,int pos2,int o){ 
            ll sum=0;
            while(pos>0) sum+=sumv[pos],pos-=lowbit(pos);
            return sum; 
        }
    }tree;
    void solve(int x,int y,int l,int r){
        if(x>y||l>r) return;
        if(l==r){ 
            for(int i=x;i<=y;++i) result[que[i]]=l; 
            return; 
        }
        int mid=(l+r)>>1,p=0,q=0,qcnt; 
        ll s; 
        for(int i=l;i<=mid;++i) {
            for(int cur=cnt[i-1]+1;cur<=cnt[i];++cur) { 
                tree.update(1,m,left[cur],right[cur],1,w[cur]);
            }
        }
        for(int i=x;i<=y;++i){
            int u=que[i];
            int siz=G[u].size(); 
            s=current[u]; 
            for(int j=0;j<siz&&s<=(ll)cost[u];++j) 
                s+=tree.query(1,m,G[u][j],G[u][j],1); 
            if(s>=cost[u]) tl[++p]=u;
            else tr[++q]=u,current[u]=s; 
        }
        for(int i=l;i<=mid;++i)
            for(int cur=cnt[i-1]+1;cur<=cnt[i];++cur) 
                tree.update(1,m,left[cur],right[cur],1,-w[cur]); 
        qcnt=x-1;
        for(int i=1;i<=p;++i) que[++qcnt]=tl[i];
        for(int i=1;i<=q;++i) que[++qcnt]=tr[i];
        solve(x,x+p-1,l,mid),solve(x+p,y,mid+1,r); 
    }
    int main(){
        //setIO("input");
        n=read(),m=read(); 
        for(int i=1;i<=m;++i) 
        {
            int a=read();  
            G[a].push_back(i); 
        }
        for(int i=1;i<=n;++i) cost[i]=read(); 
        k=read(); 
        int idx=0; 
        for(int i=1;i<=k;++i){
            int l,r,c; 
            l=read(),r=read(),c=read(); 
            if(l<=r) cnt[i]=++idx,left[idx]=l,right[idx]=r,w[idx]=c; 
            else {
                cnt[i]=++idx; 
                left[idx]=l,right[idx]=m,w[idx]=c;
                cnt[i]=++idx; 
                left[idx]=1,right[idx]=r,w[idx]=c; 
            }
        }
        for(int i=1;i<=n;++i) que[i]=i;
        cnt[++k]=++idx;
        left[idx]=1,right[idx]=m,w[idx]=(int)1e9; 
        solve(1,n,1,k);  
        for(int i=1;i<=n;++i) 
            if(result[i]==k) printf("NIE
    "); 
            else printf("%d
    ",result[i]); 
        return 0; 
    }
    

      

  • 相关阅读:
    POJ-1947 Rebuilding Roads (树形DP+分组背包)
    HDU-1011 Starship Troopers (树形DP+分组背包)
    POJ-1155 TELE (树形DP+分组背包)
    HDU-1520 Anniversary party(树形DP)
    HDU-2196 Computer (树形DP)
    HDU-1561 The more, The Better (树形DP+分组背包)
    HDU-3853 LOOPS(概率DP求期望)
    POJ 1182(权值并查集,向量?)
    HDU 3038(权值并查集)
    POJ 1733(边带权并查集+离散化)
  • 原文地址:https://www.cnblogs.com/guangheli/p/10264266.html
Copyright © 2020-2023  润新知