[LibreOJ β Round]ZQC的手办

268人阅读 评论(0) 收藏 举报
分类:

题目大意

区间对一个数取max。
区间求最小的x个比k小的数。

线段树

第一个操作很好搞。
第二个操作有个很显然的常数大做法。
实际上可以用堆把这个区间的笛卡尔树按优先级广搜。

#include<cstdio>
#include<algorithm>
#include<queue>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=500000+10,inf=1000000000;
struct dong{
    int x,y;
    friend bool operator <(dong a,dong b){
        return a.x<b.x||a.x==b.x&&a.y<b.y;
    }
    friend dong operator +(dong a,dong b){
        if (a<b) return a;else return b;
    }
} tmp;
struct suan{
    int l,r,p,v;
    friend bool operator <(suan a,suan b){
        return a.v>b.v||a.v==b.v&&a.p<b.p;
    }
} zlt;
priority_queue<suan> dl;
dong tree[maxn*4];
int mx[maxn*4],a[maxn],ans[maxn],sta[80];
bool bz[maxn*4];
int i,j,k,l,r,p,t,n,m,tot,top;
int read(){
    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;
}
void build(int p,int l,int r){
    if (l==r){
        tree[p].x=a[l];
        tree[p].y=l;
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    tree[p]=tree[p*2]+tree[p*2+1];
}
void mark(int p,int v){
    bz[p]=1;
    mx[p]=max(mx[p],v);
    if (tree[p].x<v) tree[p].x=v;
}
void down(int p){
    if (bz[p]){
        mark(p*2,mx[p]);
        mark(p*2+1,mx[p]);
        bz[p]=0;
    }
}
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);
    tree[p]=tree[p*2]+tree[p*2+1];
}
void query(int p,int l,int r,int a,int b){
    if (l==a&&r==b){
        tmp=tmp+tree[p];
        return;
    }
    down(p);
    int mid=(l+r)/2;
    if (b<=mid) query(p*2,l,mid,a,b);
    else if (a>mid) query(p*2+1,mid+1,r,a,b);
    else query(p*2,l,mid,a,mid),query(p*2+1,mid+1,r,mid+1,b);
}
int main(){
    n=read();
    fo(i,1,n) a[i]=read();
    build(1,1,n);
    m=read();
    fo(i,1,m){
        t=read();
        if (t==1){
            l=read();r=read();k=read();
            change(1,1,n,l,r,k);
        }
        else{
            l=read();r=read();k=read();j=read();
            if (r-l+1<j){
                printf("-1\n");
                continue;
            }
            while (!dl.empty()) dl.pop();
            zlt.l=l;zlt.r=r;
            tmp.x=inf;
            query(1,1,n,l,r);
            zlt.p=tmp.y;zlt.v=tmp.x;
            dl.push(zlt);
            tot=0;
            while (j--){
                zlt=dl.top();
                dl.pop();
                if (zlt.v>=k) break;
                ans[++tot]=zlt.v;
                l=zlt.l;r=zlt.r;p=zlt.p;
                if (l<p){
                    zlt.l=l;
                    zlt.r=p-1;
                    tmp.x=inf;
                    query(1,1,n,l,p-1);
                    zlt.p=tmp.y;zlt.v=tmp.x;
                    dl.push(zlt);
                }
                if (p<r){
                    zlt.l=p+1;
                    zlt.r=r;
                    tmp.x=inf;
                    query(1,1,n,p+1,r);
                    zlt.p=tmp.y;zlt.v=tmp.x;
                    dl.push(zlt);
                }
            }
            if (j>=0) printf("-1\n");
            else{
                fo(j,1,tot) printf("%d ",ans[j]);
                printf("\n");
            }
        }
    }
}
查看评论

LibreOJ #504. 「LibreOJ β Round」ZQC 的手办 线段树+堆

题意给出一个序列,要求资瓷两个操作: 1 l r k表示把[l,r]中小于k的数都改成k 2 l r k x表示从小到大输出[l,r]中小于k的x个数,若数量不足则输出-1 n,q...
  • qq_33229466
  • qq_33229466
  • 2017-06-17 09:23:54
  • 377

LibreOJ #505.「LibreOJ β Round」ZQC 的游戏 网络流

题意分析比赛的时候唯一一道想出来的题。。。直接网络流就好了。没啥好说的。代码#include #include #include #include #include #include using na...
  • qq_33229466
  • qq_33229466
  • 2017-06-17 08:07:21
  • 313

[LibreOJ β Round]ZQC的课堂

题目描述https://www.loj.ac/problem/503题解x和y是可以分开考虑的。 设si表示某维坐标的前缀和。 要求统计多少i满足si*si-1=0且min(si,si-1)...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-06-19 16:36:53
  • 333

LibreOJ #503.「LibreOJ β Round」ZQC 的课堂 线段树

题意 分析 貌似这是第一次在oj上拿rank1的说。。。 显然两维之间是互不相关的,我们可以把每一维分开处理。 对于一维向量数组a[1..n]a[1..n],对其求前缀和,设为s[...
  • qq_33229466
  • qq_33229466
  • 2018-01-23 16:04:27
  • 106

[LibreOJ β Round]ZQC的拼图

题目描述ZQC 和他的妹子在玩拼图。她们有 n (1≤n≤100) n \ (1 \leq n \leq 100) n (1≤n≤100) 块神奇的拼图,还有一块拼图板。拼图板是一个 m×m (1≤m...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-06-17 15:29:29
  • 402

「LibreOJ β Round #4」求和 莫比乌斯函数

https://loj.ac/problem/528不含平方因子的数才会有 -1 和 1才会对结果造成影响, 所有排除掉所有含有平方因子的数就好开始的时候平方是1 就是没有平方因子的情况,减去所有平...
  • Hallelujah520
  • Hallelujah520
  • 2017-09-03 18:08:29
  • 231

[分段打表 组合] LibreOJ Round #8 C .MIN&MAX I

由样例一可以知道三个数的位置关系 这四种情况其实是等价的,所以就就考虑其中的一种就好了 对于每一个三元环,我们求出它在所有排列中出现多少次,总和除以 n!n!n! 就是答案 设我们考虑的环为 a...
  • Coldef
  • Coldef
  • 2018-02-24 15:04:02
  • 63

loj#526. 「LibreOJ β Round #4」子集

给N个点,给出建边的条件,求图中的最大团,直接跑最大团模板会超时,建个对偶图,跑二分图匹配,最大团子集中点的个数就是n-匹配数 #include #include using namespace s...
  • constbh
  • constbh
  • 2017-09-06 10:46:22
  • 114

[LibreOJ β Round]ZQC的游戏

题目描述见LOJ。网络流建图裸跑。判断是否满流。 简单题。#include #include #include #define fo(i,a,b) for(i=a;i...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-06-17 15:34:01
  • 372

「LibreOJ β Round #2」贪心只能过样例 [bitset]【STL】

题目链接:https://loj.ac/problem/515 ——————————————————————————————————515. 「LibreOJ β Round #2」贪心只能过样例内...
  • qq_33184171
  • qq_33184171
  • 2017-07-03 14:51:58
  • 466
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 39万+
    积分: 1万+
    排名: 1455
    最新评论
    文章分类