BZOJ2698:染色 期望
BZOJ1492:[NOI2007]货币兑换Cash 斜率优化+cdq分治

BZOJ2527:[Poi2011]Meteors 整体二分

shinbokuow posted @ Dec 31, 2014 08:12:45 AM in BZOJ with tags 整体二分 , 1343 阅读

 

思路:

对于所有的国家整体二分最小的次数即可.

真心没有什么好说的.

值得一提的是,我们每次暴力移动版本的时间复杂度是有保证的.

这事实上是在一棵树上按照dfs序遍历.因此总的移动长度等于边权和的2倍.显然是\(O(n)\)级别的.因此在移动上面的复杂度为\(O(nlogn)\).

另外这题没必要线段树吧.

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
using namespace std;
 
namespace Fio{
    inline int getc(){
        static const int L=1<<15;static char buf[L],*S=buf,*T=buf;
        if(S==T){T=(S=buf)+fread(buf,1,L,stdin);if(S==T)return EOF;}
        return*S++;
    }
    template<typename T>inline void Get(T&x){
        int c;while(!isdigit(c=getc()));x=c-'0';
        while(isdigit(c=getc()))x=(x<<1)+(x<<3)+c-'0';
    }
    template<typename T>inline void Get(T&x,T&y){
        Get(x),Get(y);
    }
    char buf[1500010],*o=buf;
    inline void NIE(){*o++='N',*o++='I',*o++='E',*o++='\n';}
    template<typename T>inline void Print(T x){
        static int s[100];int t=0;
        if(!x)*o++=48;else{for(;x;x/=10)s[++t]=x%10;for(int i=t;i>=1;--i)*o++=48+s[i];}
        *o++='\n';
    }
    inline void Final(){fwrite(buf,1,o-buf,stdout);}
}
 
typedef double f2;
 
#define N 300010
int n,m;
 
f2 A[N];
inline void modify(int x,f2 add){for(;x<=m+1;x+=x&-x)A[x]+=add;}
inline f2 ask(int x){f2 r=0;for(;x;x-=x&-x)r+=A[x];return r;}
 
int head[N],next[N],end[N];
inline void addedge(int a,int b){static int q=1;end[q]=b,next[q]=head[a],head[a]=q++;}
 
int s[N],l[N],r[N],d[N];
 
inline void _upd(int L,int R,int d){
    modify(L,d),modify(R+1,-d);
}
inline void upd(int L,int R,int d,int rev){
    if(L<=R)_upd(L,R,rev*d);
    else _upd(L,m,rev*d),_upd(1,R,rev*d);
}
int q[N],q1[N],q2[N],cnt1,cnt2,now,ans[N];
void Solve(int insl,int insr,int lans,int rans){
    if(insl>insr)return;
    if(lans==rans){
        for(int i=insl;i<=insr;++i)ans[q[i]]=lans;
        return;
    }
    int mid=(lans+rans)/2;
    while(now<mid)upd(l[now+1],r[now+1],d[now+1],1),++now;
    while(now>mid)upd(l[now],r[now],d[now],-1),--now;
    cnt1=cnt2=0;
    for(int i=insl;i<=insr;++i){
        f2 add=0;
        for(int j=head[q[i]];j;j=next[j])add+=ask(end[j]);
        if(add<s[q[i]])q2[++cnt2]=q[i];else q1[++cnt1]=q[i];
    }
    int k=insl;
    for(int i=1;i<=cnt1;++i)q[k++]=q1[i];for(int i=1;i<=cnt2;++i)q[k++]=q2[i];
    int t=cnt1;
    Solve(insl,insl+t-1,lans,mid);
    Solve(insl+t,insr,mid+1,rans);
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("tt.in","r",stdin);
    #endif
 
    Fio::Get(n,m);
    register int i,j;int x;for(i=1;i<=m;++i)Fio::Get(x),addedge(x,i);
    for(i=1;i<=n;++i)Fio::Get(s[i]);
    int Q;Fio::Get(Q);
    for(i=1;i<=Q;++i)Fio::Get(l[i],r[i]),Fio::Get(d[i]);
    for(i=1;i<=n;++i)q[i]=i;
    l[Q+1]=r[Q+1]=1,d[Q+1]=0,Solve(1,n,1,Q+1);
    for(i=1;i<=n;++i)if(ans[i]==Q+1)Fio::NIE();else Fio::Print(ans[i]);
    return Fio::Final(),0;
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter