http://codeforces.com/gym/101234/problem/A(题目链接)
nia 一道题写了一个寒假。。。集训其实是生活开了10天
开学一周的周日晚上才搞完,。。真的佛了
wa了好多遍,拍来拍去。。不过最后A题看着run test越来越往后还是挺开心的
细节方面要考虑清楚啊 什么flag用的是哪个。。t[k]的 边界条件。。
Q
给你一段1~n的序列,m次操作,每次将区间升序或降序排列,问最后中位数是哪个
A
二分答案,将大于的赋值为1,小于(等于)赋值为0
每次进行操作模拟,用线段树维护
一次操作相当于,区间求和后将前几位赋值0/1,后几位赋值为1/0
最后复杂度O(nlogn2)
C
// <H.cpp> - 01/13/19 14:00:16
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
inline int gi() {
register int w=0,q=0;register char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')q=1,ch=getchar();
while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
return q?-w:w;
}
const int MAXN=100010;
int n,m;
struct tree{
int sum,flag;
}t[MAXN<<2];
int l[MAXN],r[MAXN],a[MAXN],b[MAXN];
void build(int l,int r,int k){
if(l==r){t[k]=(tree){b[l],b[l]};return;}
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
t[k]=(tree){t[k<<1].sum+t[k<<1|1].sum,2};
}
int sum(int l,int r,int k,int L,int R){
if(l==L&&r==R)return t[k].sum;
if(t[k].flag<2)return (R-L+1)*t[k].flag;
int mid=(l+r)>>1;
if(R<=mid)return sum(l,mid,k<<1,L,R);
else if(L>mid)return sum(mid+1,r,k<<1|1,L,R);
else return sum(l,mid,k<<1,L,mid)+sum(mid+1,r,k<<1|1,mid+1,R);
}
bool find(int pos,int l,int r,int k){
if(t[k].flag<2)return t[k].flag;
int mid=(l+r)>>1;
if(pos<=mid)return find(pos,l,mid,k<<1);
else return find(pos,mid+1,r,k<<1|1);
}
void pushdown(int k,int flag,int l,int r){
int mid=(l+r)>>1;
t[k<<1]=(tree){(mid-l+1)*flag,flag};
t[k<<1|1]=(tree){(r-mid)*flag,flag};
t[k].flag=2;
}
void update(int l,int r,int k,int flag,int L,int R){
if(t[k].flag==flag||L>R)return;
if(l==L&&r==R){t[k]=(tree){(r-l+1)*flag,flag};return;}
if(t[k].flag<2)pushdown(k,t[k].flag,l,r);
int mid=(l+r)>>1;
if(R<=mid)update(l,mid,k<<1,flag,L,R);
else if(L>mid)update(mid+1,r,k<<1|1,flag,L,R);
else update(l,mid,k<<1,flag,L,mid),update(mid+1,r,k<<1|1,flag,mid+1,R);
t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
}
int main()
{
n=gi();m=gi();
for(int i=1;i<=n;i++)a[i]=gi();
for(int i=1;i<=m;i++)l[i]=gi(),r[i]=gi();
int L=1,R=n;
while(L<R){
int mid=(L+R)>>1;
for(int i=1;i<=n;i++)if(a[i]<=mid)b[i]=0;else b[i]=1;
build(1,n,1);
for(int i=1;i<=m;i++){
int L=min(l[i],r[i]),R=max(l[i],r[i]),S=sum(1,n,1,L,R);
if(r[i]>l[i])update(1,n,1,0,L,R-S),update(1,n,1,1,R-S+1,R);
if(l[i]>r[i])update(1,n,1,1,L,L+S-1),update(1,n,1,0,L+S,R);
}
if(find((1+n)>>1,1,n,1))L=mid+1;else R=mid;
}
printf("%d",L);
return 0;
}
This passage is made by ShinaCloud.