标签:inline using problem const can bit http zoj bzoj
http://www.lydsy.com/JudgeOnline/problem.php?id=3110
整体二分+区间修改树状数组维护
#include<cstdio>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
typedef long long ll;
const int N=50011,inf=(1<<30);
int n,m,minn,maxx;
int ans[N];
ll tmp[N];
namespace BIT{
ll tr1[N],tr2[N];
inline void add(ll *a,int p,ll v){
for(;p<=n;a[p]+=v,p+=p&-p);
}
inline ll query(ll *a,int p){
ll ret=0;
for(;p;ret+=a[p],p-=p&-p);
return ret;
}
inline void _add(int l,int r,ll v){
add(tr1,l,v);add(tr1,r+1,-v);
add(tr2,l,1ll*(l-1)*v);add(tr2,r+1,-1ll*r*v);
}
inline ll _query(ll l,ll r){
ll ans1=1ll*(l-1)*query(tr1,l-1)-1ll*query(tr2,l-1);
ll ans2=1ll*r*query(tr1,r)-1ll*query(tr2,r);
return ans2-ans1;
}
}
using namespace BIT;
namespace divide{
struct question{
int a,b,c,k,pos;
}p[N],t[N];
inline void solve(int l,int r,int head,int tail){
if(head>tail)return;
if(l==r){
FOR(i,head,tail)
if(p[i].k==2)
ans[p[i].pos]=l;
return ;
}
int mid=(l+r)>>1;
FOR(i,head,tail){
if(p[i].k==1&&p[i].c>mid)_add(p[i].a,p[i].b,1ll);
if(p[i].k==2)tmp[i]=_query(p[i].a,p[i].b);
}
int top=head,d;
FOR(i,head,tail){
if(p[i].k==1&&p[i].c>mid)t[top++]=p[i],_add(p[i].a,p[i].b,-1ll);
if(p[i].k==2)if(p[i].c<=tmp[i])t[top++]=p[i];
}
d=top;
FOR(i,head,tail){
if(p[i].k==1&&p[i].c<=mid)t[top++]=p[i];
if(p[i].k==2)if(p[i].c>tmp[i])p[i].c-=tmp[i],t[top++]=p[i];
}
FOR(i,head,tail)p[i]=t[i];
solve(mid+1,r,head,d-1);
solve(l,mid,d,tail);
}
}
using namespace divide;
int main(){
scanf("%d%d",&n,&m);
minn=inf,maxx=-inf;
FOR(i,1,m){
scanf("%d%d%d%d",&p[i].k,&p[i].a,&p[i].b,&p[i].c);
if(p[i].k==2)p[i].pos=++ans[0];
if(p[i].k==1)minn=min(minn,p[i].c),maxx=max(maxx,p[i].c);
}
solve(minn,maxx,1,m);
FOR(i,1,ans[0])printf("%d\n",ans[i]);
return 0;
}
标签:inline using problem const can bit http zoj bzoj
原文地址:http://www.cnblogs.com/Stump/p/8012641.html