【HDU-4614】Vases and Flowers(线段树双查询)

11946317 2014-10-23 09:08:28 Accepted 4614 437MS 2348K rid=11946317" target="_blank" style="color:rgb(26,92,200); text-decoration:none">3340 B G++

KinderRiven

#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
/********************************
        KinderRiven
 *******************************/
#define lson (pos<<1)
#define rson (pos<<1|1)
const int maxn = 55555;
struct Node{
    int l,r;
    int v,col;
}node[maxn << 2];
int N,M;
void pushdown(int pos){
    if(node[pos].col >= 0){
        node[lson].col = node[pos].col; node[rson].col = node[pos].col;
        node[lson].v = (node[lson].r - node[lson].l + 1) * node[pos].col;
        node[rson].v = (node[rson].r - node[rson].l + 1) * node[pos].col;
        node[pos].col = -1;
    }
}
void pushup(int pos){
    node[pos].v = node[lson].v + node[rson].v;
}
void BuildTree(int L,int R,int pos){
    node[pos].l  = L;
    node[pos].r  = R;
    node[pos].col= -1;
    if(L == R){
        node[pos].v = 1;
        return;
    }
    int m = (L + R) >> 1;
    BuildTree(L,m,lson);
    BuildTree(m + 1,R,rson);
    pushup(pos);
    return;
}
void UpDate(int L,int R,int pos,int value){
    //printf("%d %d\n",node[pos].l,node[pos].r);
    if(L <= node[pos].l && node[pos].r <= R){
        node[pos].v = (node[pos].r - node[pos].l + 1) * value;
        node[pos].col = value;
        return;
    }
    pushdown(pos);
    int m = (node[pos].l + node[pos].r) >> 1;
    if(L <= m)
        UpDate(L,R,lson,value);
    if(R  > m)
        UpDate(L,R,rson,value);
    pushup(pos);
}
int Query_sum(int L,int R,int pos){
    if(L <= node[pos].l && node[pos].r <= R){
          return node[pos].v;
    }
    pushdown(pos);
    int m = (node[pos].l + node[pos].r) >> 1;
    int ret = 0;
    if(L <= m)
        ret += Query_sum(L,R,lson);
    if(R >  m)
        ret += Query_sum(L,R,rson);
    pushup(pos);
    return ret;
}
void Query(int value,int pos,int &p){
    if(node[pos].l == node[pos].r){
        p = node[pos].l;
        return;
    }
    pushdown(pos);
    int m = (node[pos].l + node[pos].r) >> 1;
    if(node[lson].v >= value)
        Query(value,lson,p);
    else
        Query(value - node[lson].v,rson,p);
    pushup(pos);
    return;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        BuildTree(0,N - 1,1);
        int op,a,b;
        for(int i = 0;i < M;i ++){
            scanf("%d%d%d",&op,&a,&b);
            //printf("%d\n",Query_sum(0,N-1,1));
            if(op == 1){  //须要改动
                int sum = Query_sum(0,N - 1,1);
                int  k1 = Query_sum(a,N - 1,1);
                int   v = sum - k1;
                //printf("%d\n",k1);
                int  p,q;
                if(k1 == 0){
                    printf("Can not put any one.\n");
                    continue;
                }
                if(k1 < b) b = k1;
                Query(v + 1,1,p);
                Query(v + b,1,q);
                UpDate(p,q,1,0);
                printf("%d %d\n",p,q);
            }
            else if(op == 2){
                int value = Query_sum(a,b,1);
                UpDate(a,b,1,1);
                printf("%d\n",b - a + 1 - value);
            }
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-10-24 15:02:55

【HDU-4614】Vases and Flowers(线段树双查询)的相关文章

HDU 4614 Vases and Flowers 线段树+二分

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614 题意:N个花瓶,两种操作. 操作1:从第a个花瓶开始放花,放最多f个,如果花瓶已经有花就跳过,直到放完,或者无更多花瓶,要求输出这次放花的第一个位置和最后一个位置,如果没放就输出Cannot... 操作2:将花瓶a到b区间内的花都扔了,然后输出扔掉的花的数目. 解题思路:花瓶有花为0,无花为1,那么实际上这是一个区间更新以及求和,求左右端点的问题.线段树节点维护一个 sum--区间和,lid-

hdu 4614 Vases and Flowers

http://acm.hdu.edu.cn/showproblem.php?pid=4614 题意:有N个花瓶,标号为0-N-1,往每一个花瓶放一朵花,然后有M个操作,输入a,b,c,如果a==1表示从b开始放花,期间有花就跳过,直到结束,如果没有放入一朵花,则输出“Can not put any one.”,否则输入第一朵花放的位置和最后一朵花放的位置. 如果a==2 则输出拔掉的花的朵数. 1 #include <cstdio> 2 #include <cstring> 3 #

HDU 4614 Vases and Flowers(线段树区间更新+二分)

Problem Description Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N-1. When she receive some flowers, she will try to put them in the vases, one flower in one vase. She randomly choose the vase A a

HDU 3397 线段树 双懒惰标记

这个是去年遗留历史问题,之前思路混乱,搞了好多发都是WA,就没做了 自从上次做了大白书上那个双重懒惰标记的题目,做这个就思路很清晰了 跟上次大白上那个差不多,这个也是有一个sets标记,代表这个区间全部置为0或者1,没有置位的时候为-1 还有个rev标记,代表翻转操作,0代表当前不翻,1代表当前翻 要注意一下优先级,发现有不同的弄法,我是这个弄得,有set操作的时候,set标记设值,并把当前节点的rev标记设为0,因为不管要不要rev,当前set操作肯定直接覆盖了 rev操作不改变set操作,在

HDOJ 4614 Vases and Flowers

线段树+二分区间 用线段树维护某一段内还有多少个花瓶可以用,二分确定插入的左右界..... Vases and Flowers Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1782    Accepted Submission(s): 700 Problem Description Alice is so popular that

hdu 1754 I Hate It 线段树 点修改

// hdu 1754 I Hate It 线段树 点修改 // // 不多说,裸的点修改 // // 继续练 #include <algorithm> #include <bitset> #include <cassert> #include <cctype> #include <cfloat> #include <climits> #include <cmath> #include <complex> #i

HDU 4902 Nice boat(线段树 区间更新)

Nice boat 大意:给你一个区间,每次可以进行两种操作,1:把区间中的数全都变成x  2:把区间中大于x的数变成gcd(a[i], x),最后输出序列. 思路:线段树成段更行,用num数组的叶子存储数据,节点当作lazy来使用. 1 #include <stdio.h> 2 const int maxn = 100005; 3 4 int num[maxn<<2]; 5 6 int gcd(int a, int b){ 7 return b?gcd(b, a%b):a; 8

hdu 4893 Wow! Such Sequence!(线段树)

题目链接:hdu 4983 Wow! Such Sequence! 题目大意:就是三种操作 1 k d, 修改k的为值增加d 2 l r, 查询l到r的区间和 3 l r, 间l到r区间上的所以数变成最近的斐波那契数,相等的话取向下取. 解题思路:线段树,对于每个节点新增一个bool表示该节点以下的位置是否都是斐波那契数. #include <cstdio> #include <cstring> #include <cstdlib> #include <algor

hdu 2852 KiKi&#39;s K-Number (线段树)

hdu 2852 题意: 一个容器,三种操作: (1) 加入一个数 e (2) 删除一个数 e,如果不存在则输出 No Elment! (3) 查询比a大的数中的第k小数,不存在就输出 Not Find! 解法: 关于第三点,可以先查询小于等于a的数的个数cnt,然后直接查询第cnt+k小数就行了 . 二分+树状数组 或者 主席树(有点杀鸡用牛刀的感觉 ...) 也是可以做的  _(:з」∠)_ code:线段树 1 #include <iostream> 2 #include <cst