bzoj3110: [Zjoi2013]K大数查询
发布时间:2020-12-14 03:13:32 所属栏目:大数据 来源:网络整理
导读:链接 http://www.lydsy.com/JudgeOnline/problem.php?id=3110 题解 惊!我突然明白 S D O I 2017 D a y 2 T 3 我为什么怒丢30分了,这道题里刚开始犯了同样的错误,虽然我正确处理了区间赋值和区间加的先后,但是我外面在打赋值标记的时候并没有将加标记清零
链接http://www.lydsy.com/JudgeOnline/problem.php?id=3110 题解 惊!我突然明白
代码//整体二分+线段树
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#define maxn 50005
#define ll long long
using namespace std;
ll N,M,ndtot,ans[maxn];
struct opt{ll type,a,b,c,id;}o[maxn];
vector<opt> v;
struct segtree
{
segtree *ch[2];
ll l,r,sum,set,add,ans;
}pool[maxn<<2],*root;
void pushdown(segtree *p)
{
if(p->set)
{
p->sum=0;
if(p->ch[0])
p->ch[0]->set=p->ch[1]->set=1,p->ch[0]->add=p->ch[1]->add=0;
p->set=0;
}
if(p->add)
{
p->sum+=(p->r-p->l+1)*p->add;
if(p->ch[0])p->ch[0]->add+=p->add,p->ch[1]->add+=p->add;
p->add=0;
}
}
void pushup(segtree *p)
{
if(!p->ch[0])return;
pushdown(p->ch[0]),pushdown(p->ch[1]);
p->sum=p->ch[0]->sum+p->ch[1]->sum;
}
void segadd(segtree *p,ll l,ll r)
{
pushdown(p);
ll mid=p->l+p->r>>1;
if(l<=p->l and r>=p->r){p->add++;return;}
if(l<=mid)segadd(p->ch[0],l,r);
if(r>mid)segadd(p->ch[1],r);
pushup(p);
}
ll segsum(segtree *p,ll r)
{
pushdown(p);
int ans=0,mid=p->l+p->r>>1;
if(l<=p->l and r>=p->r)return p->sum;
if(l<=mid)ans+=segsum(p->ch[0],r);
if(r>mid)ans+=segsum(p->ch[1],r);
return ans;
}
void build(segtree *p,ll r)
{
ll mid=l+r>>1;
p->l=l,p->r=r;
if(l==r)return;
build(p->ch[0]=pool+ ++ndtot,mid);
build(p->ch[1]=pool+ ++ndtot,mid+1,r);
}
void solve(ll l,ll r,vector<opt> &lis)
{
ll mid=ceil((l+r)/2.0),i,tmp;
vector<opt> lis1,lis2;
vector<opt>::iterator it;
if(l==r)
{
for(it=lis.begin();it!=lis.end();it++)ans[it->id]=mid;
return;
}
root->set=1;
root->add=0;
for(it=lis.begin();it!=lis.end();it++)
{
if(it->type==1 and it->c>=mid)
segadd(root,it->a,it->b),lis2.push_back(*it);
if(it->type==1 and it->c<mid)lis1.push_back(*it);
if(it->type==2)
{
tmp=segsum(root,it->b);
if(tmp>=it->c)lis2.push_back(*it);
else it->c-=tmp,lis1.push_back(*it);
}
}
solve(l,mid-1,lis1);
solve(mid,lis2);
}
ll read(ll x=0)
{
char c=getchar(); bool f=0;
while(c<48 or c>57)f=f or c=='-',c=getchar();
while(c>=48 and c<=57)x=(x<<1)+(x<<3)+c-48,c=getchar();
return f?-x:x;
}
void init()
{
ll a,i;
N=read(),M=read();
for(i=1;i<=M;i++)o[i].type=read(),o[i].a=read(),o[i].b=read(),o[i].c=read(),o[i].id=i;
build(root=pool+ ++ndtot,1,N);
for(i=1;i<=M;i++)
{
if(o[i].type==1)segadd(root,o[i].a,o[i].b);
else o[i].c=min(o[i].c,segsum(root,o[i].b));
}
for(i=1;i<=M;i++)v.push_back(o[i]);
}
int main()
{
init();
solve(-N,N,v);
for(int i=1;i<=M;i++)if(o[i].type==2)printf("%lldn",ans[i]);
return 0;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |