【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.

posted @ 2019-02-24 19:41  ShinaCloud  阅读(390)  评论(0编辑  收藏  举报