题目链接 :http://www.fjutacm.com/Contest.jsp?cid=440#P10
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define ls 2*rt
#define rs 2*rt+1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define ll long long
using namespace std;
typedef pair<int,int> pii;
const ll inf = 0x3f3f3f3f;
/*void dis(int a[], int n){
printf("总数为%d个\n",n);
for(int i = 0; i < n; i++) cout<<a[i]<<", ";
cout<<endl<<"------------------"<<endl;
}*/
const int mx = 1e5+10;
struct no{
int l,r,lg,rg,ms,cnt;
}p[mx*4];
int vis[mx];
void build(int rt,int L, int R){
p[rt].l = L; p[rt].r = R;
p[rt].lg = p[rt].rg = p[rt].cnt = p[rt].ms = p[rt].cnt = 0;
if(L == R){
return ;
}
int mid = (L+R)/2;
build(lson);
build(rson);
}
void push_up(int rt){
if(p[ls].r - p[ls].l + 1 == p[ls].ms){
p[rt].lg = p[ls].ms+p[rs].lg; //记得连上右子树的左区间
}
else{
p[rt].lg = p[ls].lg;
}
if(p[rs].r - p[rs].l + 1 == p[rs].ms){
p[rt].rg = p[rs].ms+p[ls].rg;
}
else{
p[rt].rg = p[rs].rg;
}
//p[rt].ms = max(p[rt].ms,max(p[ls].ms,p[rs].ms)); //这样写是错的
//p[rt].ms = max(p[rt].ms,p[ls].rg+p[rs].lg);
p[rt].ms = max(p[ls].rg+p[rs].lg,max(p[ls].ms,p[rs].ms));
if(p[rt].r - p[rt].l +1 == p[rt].ms)
p[rt].cnt = 1;
else{
p[rt].cnt = p[ls].cnt + p[rs].cnt;
if(p[ls].rg>0&&p[rs].lg>0)
p[rt].cnt--;
}
}
void update(int rt, int L, int R,int po){
if(po<L || po>R){
return;
}
if(L == R){
p[rt].lg = p[rt].rg = p[rt].ms = 1^p[rt].ms;
if(vis[L]){
p[rt].cnt = 0;
}
else
p[rt].cnt = 1;
return; //不要忘记
}
int mid = (L+R)/2;
if(po<=mid)
update(lson,po);
else
update(rson,po);
push_up(rt);
}
int main(){
int n,q,te;
scanf("%d%d",&n,&q);
// memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i++)
vis[i] = 1;
build(1,1,n);
while(q--){
scanf("%d",&te);
if(vis[te]){
vis[te] = 0;
update(1,1,n,te);
}
else{
vis[te] = 1;
update(1,1,n,te);
}
printf("%d %d\n",p[1].cnt,p[1].ms);
}
return 0;
}
区间求最小和最大写了一半 写不下去以后继续写
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define ls 2*rt
#define rs 2*rt+1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define ll long long
using namespace std;
typedef pair<int,int> pii;
const ll inf = 0x3f3f3f3f;
/*void dis(int a[], int n){
printf("总数为%d个\n",n);
for(int i = 0; i < n; i++) cout<<a[i]<<", ";
cout<<endl<<"------------------"<<endl;
}*/
const int mx = 1e5+10;
struct no{
int l,r,lg,rg,mxs,mis,cnt,Max; //cnt是区间个数 mxs是区间最大长度 mis是区间最短长度 Max是最值
}p[mx*4];
int vis[mx];
void build(int rt,int L, int R){
p[rt].l = L; p[rt].r = R;
// p[rt].lg = p[rt].rg = p[rt].cnt = p[rt].ms = 0;
if(L == R){
p[rt].lg = p[rt].rg = p[rt].mxs = p[rt].mis = 1;
p[rt].cnt = 1;
scanf("%d",&p[rt].Max);
return ;
}
int mid = (L+R)/2;
build(lson);
build(rson);
p[rt].Max = max(p[ls].Max,p[rs].Max);
push_up(rt);
}
void push_up(int rt){
if(p[ls].r - p[ls].l + 1 == p[ls].mxs){
p[rt].lg = p[ls].mxs+p[rs].lg; //记得连上右子树的左区间
}
else{
p[rt].lg = p[ls].lg;
}
if(p[rs].r - p[rs].l + 1 == p[rs].mxs){
p[rt].rg = p[rs].mxs+p[ls].rg;
}
else{
p[rt].rg = p[rs].rg;
}
//p[rt].ms = max(p[rt].ms,max(p[ls].ms,p[rs].ms)); //这样写是错的
//p[rt].ms = max(p[rt].ms,p[ls].rg+p[rs].lg);
p[rt].mxs = max(p[ls].rg+p[rs].lg,max(p[ls].mxs,p[rs].mxs)); //合并最大
p[rt].mis = min(p[ls].rg+p[rs].lg,min(p[ls].mis,p[rs].mis)); //合并最小
if(p[rt].r - p[rt].l +1 == p[rt].ms)
p[rt].cnt = 1;
else{
p[rt].cnt = p[ls].cnt + p[rs].cnt;
if(p[ls].rg>0&&p[rs].lg>0)
p[rt].cnt--;
}
}
void update(int rt, int L, int R,int x){
if(p[rx].Max < x){
return;
}
if(L == R){
p[rt].Max = -1;
p[rt].lg = p[rt].rg = p[rt].ms = 0;
p[rt].cnt = 0; //区间个数
return; //不要忘记
}
int mid = (L+R)/2;
if(x <= p[ls].Max)
update(lson,x);
if(x <= p[rs].Max)
update(rson,x);
p[rt].Max = max(p[ls].Max,p[rs].Max);
push_up(rt);
}
int main(){
int n,q,te;
scanf("%d%d",&n,&q);
// memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i++)
vis[i] = 1;
build(1,1,n);
while(q--){
scanf("%d",&te);
if(vis[te]){
vis[te] = 0;
update(1,1,n,te);
}
else{
vis[te] = 1;
update(1,1,n,te);
}
printf("%d %d\n",p[1].cnt,p[1].ms);
}
return 0;
}
wa
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define ls 2*rt
#define rs 2*rt+1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define ll long long
using namespace std;
typedef pair<int,int> pii;
const ll inf = 0x3f3f3f3f;
/*void dis(int a[], int n){
printf("总数为%d个\n",n);
for(int i = 0; i < n; i++) cout<<a[i]<<", ";
cout<<endl<<"------------------"<<endl;
}*/
const int mx = 1e5+10;
int gg;
struct no{
int l,r,lg,rg,mxs,mis,cnt,Max; //cnt是区间个数 mxs是区间最大长度 mis是区间最短长度 Max是最值
}p[mx*4];
int num[mx];
void build(int rt,int L, int R){
p[rt].l = L; p[rt].r = R;
// p[rt].lg = p[rt].rg = p[rt].cnt = p[rt].ms = 0;
if(L == R){
p[rt].lg = p[rt].rg = p[rt].mxs = 1;
p[rt].cnt = 1;
p[rt].mis = inf;
gg++;
p[rt].Max = num[gg];
// lx = min(lx,p[rt].Max);
// rx = max(rx,p[rt].Max);
return ;
}
int mid = (L+R)/2;
build(lson);
build(rson);
p[rt].Max = max(p[ls].Max,p[rs].Max);
p[rt].lg = p[rt].rg = p[rt].mxs = (p[ls].mxs+p[rs].mxs);
p[rt].cnt = 1;
p[rt].mis = inf;
}
void push_up(int rt){
if(p[ls].r - p[ls].l + 1 == p[ls].mxs){
p[rt].lg = p[ls].mxs+p[rs].lg; //记得连上右子树的左区间
}
else{
p[rt].lg = p[ls].lg;
}
if(p[rs].r - p[rs].l + 1 == p[rs].mxs){
p[rt].rg = p[rs].mxs+p[ls].rg;
}
else{
p[rt].rg = p[rs].rg;
}
/* if(rt == 1){
cout<<"*="<<p[2].mis<<"*="<<p[3].mis<<endl;
cout<<p[ls].rg<<" "<<p[rs].lg<<endl;
}*/
p[rt].mxs = max(p[ls].rg+p[rs].lg,max(p[ls].mxs,p[rs].mxs)); //合并最大
if(p[ls].r-p[ls].l+1 == p[ls].mxs || p[rs].r-p[rs].l+1 == p[rs].mxs){ //如果其中一颗子树区间连续
p[rt].mis = min(p[ls].mis,p[rs].mis);
// cout<<"jin"<<endl;
}
else {
if(p[ls].rg+p[rs].lg == 0){
p[rt].mis = min(p[ls].mis,p[rs].mis);
}
else
p[rt].mis = min(p[ls].rg+p[rs].lg,min(p[ls].mis,p[rs].mis));
}
// if(p[rt].mis == 0) //0是没有用的
// p[rt].mis = inf;
if(p[rt].r - p[rt].l +1 == p[rt].mxs)
p[rt].cnt = 1;
else{
p[rt].cnt = p[ls].cnt + p[rs].cnt;
if(p[ls].rg>0&&p[rs].lg>0)
p[rt].cnt--;
}
}
void update(int rt, int L, int R,int x){
if(p[rt].Max < x){
return;
}
// cout<<"jin"<<endl;
if(L == R){
// cout<<"去掉:"<<p[rt].Max<<endl;
p[rt].Max = -1;
p[rt].lg = p[rt].rg = p[rt].mxs = 0;
p[rt].cnt = 0; //区间个数
return; //不要忘记
}
int mid = (L+R)/2;
if(x <= p[ls].Max)
update(lson,x);
if(x <= p[rs].Max)
update(rson,x);
p[rt].Max = max(p[ls].Max,p[rs].Max);
push_up(rt);
}
int main(){
int n,q,te;
freopen("F:\\in.txt","r",stdin);
while(scanf("%d",&n) != EOF){
//lx = inf;
//rx = -inf;
for(int i = 1; i <= n; i++){
scanf("%d",num+i);
}
gg = 0;
build(1,1,n);
sort(num+1,num+n+1);
num[n+1] = num[n]+1;
int ans = 0,co = -1;
// num[10]=1;
//for(int i = 10; i>=10; i--){
for(int i = n+1; i>1; i--){
cout<<num[i]<<"?"<<endl;
if(i < n && num[i]+1!=num[i+1]){
// cout<<num[i]+1<<"?"<<endl;
//cout<<"**"<<num[i]+1<<endl;
update(1,1,n,num[i]+1);
int a = p[1].lg,b=p[1].rg,c;
if(a == 0) a = p[1].mis;
if(b == 0) b = p[1].mis;
c = min(min(a,b),p[1].mis);
if(num[i] == 9)
//cout<<c<<"++"<<p[1].mxs<<endl;
if(c == p[1].mxs && p[1].cnt >= co){
ans = num[i]+1;
co = p[1].cnt;
}
}
update(1,1,n,num[i]);
int a = p[1].lg,b=p[1].rg,c;
if(a == 0) a = p[1].mis;
if(b == 0) b = p[1].mis;
c = min(min(a,b),p[1].mis);
if(c == p[1].mxs && p[1].cnt >= co){
ans = num[i];
co = p[1].cnt;
}
}
cout<<ans<<endl;
//cout<<"次数为:"<<co<<endl;
}
return 0;
}