线段树区间合并 给屌丝和女神各开一个线段树即可
但是注意文字输出一定要复制样例 题目TM把英文单引号写成中文的! 为什么要这样对我们?
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int l;
int r;
int left1;
int right1;
int all1;
int laz1;
int left2;
int right2;
int all2;
int laz2;
};
node tree[800010];
int n;
void changeI(int cur,int val)
{
tree[cur].left1=(tree[cur].r-tree[cur].l+1)*val;
tree[cur].right1=(tree[cur].r-tree[cur].l+1)*val;
tree[cur].all1=(tree[cur].r-tree[cur].l+1)*val;
return;
}
void changeII(int cur,int val)
{
tree[cur].left2=(tree[cur].r-tree[cur].l+1)*val;
tree[cur].right2=(tree[cur].r-tree[cur].l+1)*val;
tree[cur].all2=(tree[cur].r-tree[cur].l+1)*val;
return;
}
void pushup(int cur)
{
tree[cur].left1=tree[2*cur].left1;
if(tree[cur].left1==tree[2*cur].r-tree[2*cur].l+1) tree[cur].left1+=tree[2*cur+1].left1;
tree[cur].right1=tree[2*cur+1].right1;
if(tree[cur].right1==tree[2*cur+1].r-tree[2*cur+1].l+1) tree[cur].right1+=tree[2*cur].right1;
tree[cur].all1=max(tree[2*cur].right1+tree[2*cur+1].left1,max(tree[2*cur].all1,tree[2*cur+1].all1));
tree[cur].left2=tree[2*cur].left2;
if(tree[cur].left2==tree[2*cur].r-tree[2*cur].l+1) tree[cur].left2+=tree[2*cur+1].left2;
tree[cur].right2=tree[2*cur+1].right2;
if(tree[cur].right2==tree[2*cur+1].r-tree[2*cur+1].l+1) tree[cur].right2+=tree[2*cur].right2;
tree[cur].all2=max(tree[2*cur].right2+tree[2*cur+1].left2,max(tree[2*cur].all2,tree[2*cur+1].all2));
return;
}
void pushdown(int cur)
{
if(tree[cur].laz1!=-1)
{
changeI(2*cur,tree[cur].laz1);
changeI(2*cur+1,tree[cur].laz1);
tree[2*cur].laz1=tree[2*cur+1].laz1=tree[cur].laz1;
tree[cur].laz1=-1;
}
if(tree[cur].laz2!=-1)
{
changeII(2*cur,tree[cur].laz2);
changeII(2*cur+1,tree[cur].laz2);
tree[2*cur].laz2=tree[2*cur+1].laz2=tree[cur].laz2;
tree[cur].laz2=-1;
}
return;
}
void build(int l,int r,int cur)
{
int m;
tree[cur].l=l;
tree[cur].r=r;
tree[cur].laz1=-1;
tree[cur].laz2=-1;
if(l==r)
{
tree[cur].left1=tree[cur].right1=tree[cur].all1=1;
tree[cur].left2=tree[cur].right2=tree[cur].all2=1;
return;
}
m=(l+r)/2;
build(l,m,2*cur);
build(m+1,r,2*cur+1);
pushup(cur);
return;
}
int queryI(int val,int cur)
{
if(tree[cur].all1<val) return -1;
if(tree[cur].l==tree[cur].r) return tree[cur].l;
pushdown(cur);
if(tree[2*cur].all1>=val) return queryI(val,2*cur);
else if(tree[2*cur].right1+tree[2*cur+1].left1>=val) return tree[2*cur].r-tree[2*cur].right1+1;
else return queryI(val,2*cur+1);
}
void updateI(int pl,int pr,int val,int cur)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
changeI(cur,val);
tree[cur].laz1=val;
return;
}
pushdown(cur);
if(pl<=tree[2*cur].r) updateI(pl,pr,val,2*cur);
if(pr>=tree[2*cur+1].l) updateI(pl,pr,val,2*cur+1);
pushup(cur);
return;
}
int queryII(int val,int cur)
{
if(tree[cur].all2<val) return -1;
if(tree[cur].l==tree[cur].r) return tree[cur].l;
pushdown(cur);
if(tree[2*cur].all2>=val) return queryII(val,2*cur);
else if(tree[2*cur].right2+tree[2*cur+1].left2>=val) return tree[2*cur].r-tree[2*cur].right2+1;
else return queryII(val,2*cur+1);
}
void updateII(int pl,int pr,int val,int cur)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
changeII(cur,val);
tree[cur].laz2=val;
return;
}
pushdown(cur);
if(pl<=tree[2*cur].r) updateII(pl,pr,val,2*cur);
if(pr>=tree[2*cur+1].l) updateII(pl,pr,val,2*cur+1);
pushup(cur);
return;
}
int main()
{
int t,cas,q,val,p,l,r;
char op[20];
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d%d",&n,&q);
build(1,n,1);
printf("Case %d:\n",cas);
while(q--)
{
scanf("%s",op);
if(op[0]=='D')
{
scanf("%d",&val);
p=queryI(val,1);
if(p==-1) printf("fly with yourself\n");
else
{
updateI(p,p+val-1,0,1);
printf("%d,let's fly\n",p);
}
}
else if(op[0]=='N')
{
scanf("%d",&val);
p=queryI(val,1);
if(p==-1)
{
p=queryII(val,1);
if(p==-1) printf("wait for me\n");
else
{
updateI(p,p+val-1,0,1);
updateII(p,p+val-1,0,1);
printf("%d,don't put my gezi\n",p);
}
}
else
{
updateI(p,p+val-1,0,1);
updateII(p,p+val-1,0,1);
printf("%d,don't put my gezi\n",p);
}
}
else
{
scanf("%d%d",&l,&r);
updateI(l,r,1,1);
updateII(l,r,1,1);
printf("I am the hope of chinese chengxuyuan!!\n");
}
}
}
return 0;
}