【Codeforces】Hacker Cups and Balls
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.