333人阅读 评论(0)

# 题目描述

https://www.loj.ac/problem/503

# 题解

x和y是可以分开考虑的。

1、max(si,si-1)<=0
2、min(si,si-1)>=0

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=100000+10;
int tree[maxn][2],father[maxn],key[maxn],size[maxn],da[maxn];
int i,j,k,l,t,n,m,root,tot,top,now;
char ch;
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9'){
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
char get(){
char ch=getchar();
while (ch!='B'&&ch!='F'&&ch!='C'&&ch!='Q') ch=getchar();
return ch;
}
void mark(int p,int v){
}
void down(int p){
}
}
void change(int p,int l,int r,int a,int b,int v){
if (l==a&&r==b){
mark(p,v);
return;
}
down(p);
int mid=(l+r)/2;
if (b<=mid) change(p*2,l,mid,a,b,v);
else if (a>mid) change(p*2+1,mid+1,r,a,b,v);
else change(p*2,l,mid,a,mid,v),change(p*2+1,mid+1,r,mid+1,b,v);
}
int query(int p,int l,int r,int a){
if (!a) return 1;
down(p);
int mid=(l+r)/2;
if (a<=mid) return query(p*2,l,mid,a);else return query(p*2+1,mid+1,r,a);
}
int pd(int x){
return tree[father[x]][1]==x;
}
void update(int x){
size[x]=size[tree[x][0]]+size[tree[x][1]]+1;
}
void rotate(int x){
int y=father[x],z=pd(x);
father[x]=father[y];
if (father[y]) tree[father[y]][pd(y)]=x;
tree[y][z]=tree[x][1-z];
if (tree[x][1-z]) father[tree[x][1-z]]=y;
tree[x][1-z]=y;
father[y]=x;
if (root==y) root=x;
update(y);
update(x);
}
void mark2(int x,int v){
da[x]+=v;
}
void clear(int x){
if (!x) return;
if (da[x]){
key[x]+=da[x];
mark2(tree[x][0],da[x]);
mark2(tree[x][1],da[x]);
da[x]=0;
}
}
void remove(int x,int y){
top=0;
while (x!=y){
sta[++top]=x;
x=father[x];
}
while (top) clear(sta[top--]);
}
void splay(int x,int y){
remove(x,y);
while (father[x]!=y){
if (father[father[x]]!=y)
if (pd(father[x])==pd(x)) rotate(father[x]);else rotate(x);
rotate(x);
}
}
void insert(int &x,int y){
if (!x){
x=y;
size[x]=1;
return;
}
clear(x);
if (key[y]<=key[x]){
insert(tree[x][0],y);
father[tree[x][0]]=x;
}
else{
insert(tree[x][1],y);
father[tree[x][1]]=x;
}
update(x);
}
int find(int x){
if (!x) return 0;
clear(x);
if (key[x]<=0) return find(tree[x][1])+size[tree[x][0]]+1;
else return find(tree[x][0]);
}
int find2(int x){
if (!x) return 0;
clear(x);
if (key[x]>=0) return find2(tree[x][0])+size[tree[x][1]]+1;
else return find2(tree[x][1]);
}
int merge(int a,int b){
if (!a||!b) return a+b;
int t=a;
while (tree[t][1]) t=tree[t][1];
splay(t,0);
tree[t][1]=b;
father[b]=t;
update(t);
return t;
}
void work(int p){
s[0]=a[0][p];
fo(i,1,n) s[i]=s[i-1]+a[i][p];
fo(i,1,n) da[i]=0;
root=now=0;
fo(i,1,n){
key[i]=max(s[i],s[i-1]);
father[i]=tree[i][0]=tree[i][1]=0;
if (key[i]<=0) now++;
insert(root,i);
splay(i,0);
}
j=1;
fo(i,1,m){
j--;
key[j]=max(query(1,1,n,j),query(1,1,n,j-1));
father[j]=tree[j][0]=tree[j][1]=0;
insert(root,j);
splay(j,0);
}
splay(j,0);
clear(j);
father[tree[j][0]]=father[tree[j][1]]=0;
root=merge(tree[j][0],tree[j][1]);
j++;
}
now-=find(root);
splay(j,0);
clear(j);
father[tree[j][0]]=father[tree[j][1]]=0;
root=merge(tree[j][0],tree[j][1]);
mark2(root,t);
change(1,1,n,j,n,t);
key[j]=max(query(1,1,n,j),query(1,1,n,j-1));
father[j]=tree[j][0]=tree[j][1]=0;
insert(root,j);
splay(j,0);
now+=find(root);
}
}
fo(i,1,n) da[i]=0;
root=now=0;
fo(i,1,n){
key[i]=min(s[i],s[i-1]);
father[i]=tree[i][0]=tree[i][1]=0;
if (key[i]>=0) now++;
insert(root,i);
splay(i,0);
}
j=1;
fo(i,1,m){
j--;
key[j]=min(query(1,1,n,j),query(1,1,n,j-1));
father[j]=tree[j][0]=tree[j][1]=0;
insert(root,j);
splay(j,0);
}
splay(j,0);
clear(j);
father[tree[j][0]]=father[tree[j][1]]=0;
root=merge(tree[j][0],tree[j][1]);
j++;
}
now-=find2(root);
splay(j,0);
clear(j);
father[tree[j][0]]=father[tree[j][1]]=0;
root=merge(tree[j][0],tree[j][1]);
mark2(root,t);
change(1,1,n,j,n,t);
key[j]=min(query(1,1,n,j),query(1,1,n,j-1));
father[j]=tree[j][0]=tree[j][1]=0;
insert(root,j);
splay(j,0);
now+=find2(root);
}
}
fo(i,1,tot) ans[i]+=n;
}
int main(){
//freopen("data.in","r",stdin);freopen("data.out","w",stdout);
a[0][0]=a[0][1]=1;
fo(i,1,m){
ch=get();
else{
}
}
work(0);
work(1);
fo(i,1,tot) printf("%d\n",ans[i]);
}

个人资料
等级：
访问量： 39万+
积分： 1万+
排名： 1455
最新评论
文章分类