首页 > 其他 > 详细

kuangbin带你飞--线段树二

时间:2019-09-20 13:19:46      阅读:57      评论:0      收藏:0      [点我收藏+]

j

题意:

每一个人都有一个boss,没有boss的那一个人是最终大boss,每一次发放任务个x,他的所有的以他为boss的人也就是说子树(包括自己)全部都开始做这个任务。
我们可以看到这一棵树是无序的,而且是并不是二叉树,所以就需要转换。
既然跟子树有关,我们就深度优先遍历,用dfs来建立序列,一个点有开始和结束的编号,他的所有子树的编号一定会在开始和节点之间,这样子就可以做到区间更新。
所以我们根据dfs序列来进行建立线段树的操作,单点更新到开始的编号,区间更新的话就是这个节点开始到结束的编号。
这里还利用了类似并查集的原理来寻炸根节点。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
    char ch = getchar(); int x = 0, f = 1;
    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;
}
typedef pair<int, int> pir;
const int N = 50010;
int T;
int n, m,tot,cnt;
int st[N], ed[N];
struct  {
    int to, next;
}edge[N];
int head[N];
int tree[N<<2];
int lazy[N << 2];
int uset[N];
int find_set(int x)
{
    if (uset[x] != x)

        uset[x] = find_set(uset[x]);

    return uset[x];

}
void build(int l, int r, int root)
{
    lazy[root] = -1;
    tree[root] = -1;
    if (l == r)
    {
        return;                                                         
    }
    int mid = (l + r) >> 1;
    build(l, mid, root << 1);
    build(mid + 1, r, root << 1 | 1);
}
void pushdown(int root)
{
    if (lazy[root] != -1)
    {
        tree[root << 1] = lazy[root];
        tree[root << 1 | 1] = lazy[root];
        lazy[root << 1] = lazy[root];
        lazy[root << 1 | 1] = lazy[root];
        lazy[root] = -1;
    }
}
void addedge(int f,int t)
{
    edge[tot].to = t;
    edge[tot].next = head[f];
    head[f] = tot++;
}
void dfs(int p)
{
    st[p] = ++cnt;
    int i = head[p];
    while(i!=-1)
    {
        dfs(edge[i].to);
        i = edge[i].next;
    }
    ed[p] = cnt;
}
void update(int l, int r, int root, int lf, int rt, int val)
{
    if (lf <= l && r <= rt)
    {
        tree[root] = val; lazy[root] = val; return;
    }
    pushdown(root);
    int mid = (l + r) >> 1;
    if (lf <= mid)update(l, mid, root << 1, lf, rt, val);
    if (rt > mid)update(mid + 1, r, root << 1 | 1, lf, rt, val);
}
void querry(int l, int r, int root ,int pos)
{
    if (l == r)
    {
        printf("%d\n", tree[root]);
        return;
    }
    pushdown(root);
    int mid = (l + r) >> 1;
    if (pos <= mid)return querry(l, mid, root << 1, pos);
    else return querry(mid + 1, r, root << 1 | 1, pos);
}
int main()
{
    scanf("%d", &T);
    upd(p, 1, T)
    {
        scanf("%d", &n);
        upd(i, 0, n)uset[i] = i,head[i]=-1;
        tot = 0; cnt = 0;
        int x, y;
    //  cout << tot << " " << cnt << endl;
        up(i, 0, n - 1)
        {
            scanf("%d %d",&x,&y); addedge(y, x); uset[x] = y;
        }
        int rt = find_set(1);
        dfs(rt);
        build(1, cnt, 1);
        scanf("%d", &m);
        char op[3];
        printf("Case #%d:\n", p);
        while (m--)
        {
            scanf("%s", op);
            if (op[0] == 'C')
            {
                scanf("%d", &x);
                querry(1, n, 1, st[x]);
            //  printf("%d", querry(1, cnt, 1, st[x]));
            }
            else
            {
                scanf("%d %d", &x, &y);
                update(1, cnt, 1, st[x], ed[x], y);
            }
        }
    }
    return 0;
    
}

K

题意

给出一系列操作,有给这一个区间乘以一个数字的,有给这一个区间加上一个数字的,有询问这一个区间,平方和,立方和的。
这里询问操作就不再赘述,网上题解写的好的很。
主要是细节 ,不要粗心。
先做乘法后做加法。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
    char ch = getchar(); int x = 0, f = 1;
    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;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
const int N = 1e5 + 10;
const int mod = 10007;
const int MOD = 10007;
ll sum1[N << 2];
ll sum2[N << 2];
ll sum3[N << 2];
ll st[N << 2];
ll mul[N << 2];
ll add[N << 2];
int x, y, z, op;
int n, m;
ll madd(ll x, ll y)
{
    return (x%mod + y % mod) % mod;
}
ll mmul(ll x, ll y)
{
    return x * y%mod;
}
void pushup(int root)
{
    sum1[root] = madd(sum1[root << 1], sum1[root << 1 | 1]);
    sum2[root] = madd(sum2[root << 1], sum2[root << 1 | 1]);
    sum3[root] = madd(sum3[root << 1], sum3[root << 1 | 1]);
}
void pushdown(int rt, int len)
{
    int root = rt;
    if (st[root])
    {
        add[root << 1] = add[root << 1 | 1] = 0;
        mul[root << 1] = mul[root << 1 | 1] = 1;
        st[root << 1] = st[root];
        st[root << 1 | 1] = st[root];
        ll lenl = len - (len >> 1); ll lenr = (len >> 1);
        sum1[root << 1] = mmul(st[root], lenl%mod);
        sum1[root << 1 | 1] = mmul(st[root], lenr%mod);
        sum2[root << 1] = lenl % mod * (st[root] * st[root] % mod) % mod;
        sum2[root << 1 | 1] = lenr % mod * (st[root] * st[root] % mod) % mod;
        sum3[root << 1] = lenl % mod * ((st[root] * st[root]) % mod*st[root] % mod) % mod;
        sum3[root << 1 | 1] = lenr % mod * ((st[root] * st[root]) % mod*st[root] % mod) % mod;
        st[root] = 0;
    }
    if (mul[rt] != 1) {    //这个就是mul[rt] != 1 , 当时我这里没注意所以TLE了
        mul[rt << 1] = (mul[rt << 1] * mul[rt]) % MOD;
        mul[rt << 1 | 1] = (mul[rt << 1 | 1] * mul[rt]) % MOD;
        if (add[rt << 1])    //注意这个也要下放
            add[rt << 1] = (add[rt << 1] * mul[rt]) % MOD;
        if (add[rt << 1 | 1])
            add[rt << 1 | 1] = (add[rt << 1 | 1] * mul[rt]) % MOD;
        ll tmp = (((mul[rt] * mul[rt]) % MOD * mul[rt]) % MOD);
        sum1[rt << 1] = (sum1[rt << 1] * mul[rt]) % MOD;
        sum1[rt << 1 | 1] = (sum1[rt << 1 | 1] * mul[rt]) % MOD;
        sum2[rt << 1] = (sum2[rt << 1] % MOD) * ((mul[rt] * mul[rt]) % MOD) % MOD;
        sum2[rt << 1 | 1] = (sum2[rt << 1 | 1] % MOD) * ((mul[rt] * mul[rt]) % MOD) % MOD;
        sum3[rt << 1] = (sum3[rt << 1] % MOD) * tmp % MOD;
        sum3[rt << 1 | 1] = (sum3[rt << 1 | 1] % MOD) * tmp % MOD;
        mul[rt] = 1;
    }
    if (add[root])
    {
        add[root << 1] = madd(add[root << 1], add[root]);
        add[root << 1 | 1] = madd(add[root << 1 | 1], add[root]);
        ll tp2 = add[root] * add[root] % mod;
        ll tp3 = tp2 * add[root] % mod;
        ll tmp = (add[rt] * add[rt] % MOD) * add[rt] % MOD;        //注意sum3 , sum2 , sum1的先后顺序
        sum3[rt << 1] = (sum3[rt << 1] + (tmp * (len - (len >> 1)) % MOD) + 3 * add[rt] * ((sum2[rt << 1] + sum1[rt << 1] * add[rt]) % MOD)) % MOD;
        sum3[rt << 1 | 1] = (sum3[rt << 1 | 1] + (tmp * (len >> 1) % MOD) + 3 * add[rt] * ((sum2[rt << 1 | 1] + sum1[rt << 1 | 1] * add[rt]) % MOD)) % MOD;
        sum2[root << 1] = (sum2[root << 1] + 2ll * sum1[root << 1] * add[root] % mod + (1ll * (len - (len >> 1))*tp2) % mod) % mod;
        sum2[root << 1 | 1] = (sum2[root << 1 | 1] + 2ll * sum1[root << 1 | 1] * add[root] % mod + 1ll * (len >> 1)*tp2 % mod) % mod;
        sum1[root << 1] = madd(sum1[root << 1], mmul(len - (len >> 1), add[root]));
        sum1[root << 1 | 1] = madd(sum1[root << 1 | 1], mmul((len >> 1), add[root]));
        add[root] = 0;
    }
}
void build(int l, int r, int root)
{
    st[root] = 0;
    mul[root] = 1;
    add[root] = 0;
    sum1[root] = sum2[root] = sum3[root] = 0;
    if (l == r)return;
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op, int val)
{
    if (lf <= l && r <= rt)
    {
        if (op == 1)
        {
            add[root] = (add[root] + val) % mod;
            ll tp2 = 1ll * val*val % mod;
            ll tp3 = 1ll * tp2 * val % mod;
            sum3[root] = (sum3[root] + 3ll * sum2[root] * val%mod + 3ll * sum1[root] * tp2%mod + tp3 * 1ll * (r - l + 1) % mod) % mod;
            sum2[root] = (sum2[root] + 2ll * sum1[root] * val%mod + tp2 * 1ll * (r - l + 1) % mod) % mod;
            sum1[root] = (sum1[root] + 1ll * (r - l + 1)*val) % mod;
        }
        if (op == 2)
        {
            mul[root] = (1ll * mul[root] * val) % mod;
            add[root] = (1ll * add[root] * val) % mod;
            sum3[root] = (sum3[root] * ((1ll * val*val%mod)*val%mod)) % mod;
            sum2[root] = (sum2[root] * (1ll * val*val%mod)) % mod;
            sum1[root] = (1ll * sum1[root] * val) % mod;
        }
        if (op == 3)
        {
            st[root] = val;
            add[root] = 0;
            mul[root] = 1;
            sum3[root] = 1ll * (r - l + 1)*((1ll * val*val) % mod*val%mod) % mod;
            sum2[root] = 1ll * (r - l + 1)*(1ll * val*val%mod) % mod;
            sum1[root] = 1ll * (r - l + 1)*val%mod;
        }
        return;
    }
    pushdown(root, (r - l + 1));
    int mid = (l + r) >> 1;
    if (lf <= mid)update(lson, lf, rt, op, val);
    if (rt > mid)update(rson, lf, rt, op, val);
    pushup(root);
}
ll querry(int l, int r, int root, int lf, int rt, int p)
{
    if (lf <= l && r <= rt)
    {
        if (p == 1)return sum1[root] % mod;
        if (p == 2)return sum2[root] % mod;
        if (p == 3)return sum3[root] % mod;
    }
    pushdown(root, r - l + 1);
    int mid = (l + r) >> 1;
    ll ans = 0;
    if (lf <= mid)ans += querry(lson, lf, rt, p);
    if (rt > mid)ans += querry(rson, lf, rt, p);
    ans %= mod;
    return ans;
}
int main()
{
    while (cin >> n >> m && (n + m))
    {
        build(1, n, 1);
        up(i, 0, m)
        {
            op = read(), x = read(), y = read(), z = read();
            if (op == 4)
            {
                printf("%lld\n", querry(1, n, 1, x, y, z));
            }
            else
            {
                update(1, n, 1, x, y, op, z);
            }
        }
    }
    return 0;
}

L 题意

给出几个操作,第一个操作是把花插入花瓶,并指定位置,一直插到n-1
或者花不够了结束。如果遇到花瓶有花了,跳过。也就是从pos到n-1,找空位置插入。
询问就是区间内有几个空的花瓶。
我们反过来用1表示空,0表示有。
这样区间和就可以表示这个区间还有几个空的花瓶了。
我们这里运用二分的思想。对于一个区间来说,他的和是上升不会下降的。
例如11100011101,即便是被插了花,和来说也是不严格单调递增的。
所以我们能用二分。先二分起点,也就是querry查询sum=1,再二分终点,查询sum=花数目,最后更新这个区间,置零即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int read()
{
    char ch = getchar(); int x = 0, f = 1;
    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;
}
typedef pair<int, int> pir;
const int N = 5e4 + 10;
int T, n, m,op;
int tree[N << 2];
int lazy[N << 2];
void pushup(int root)
{
    tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int len)
{
    if (lazy[root]!=-1)
    {
        tree[lrt] = (len - (len >> 1))*lazy[root];
        tree[rrt] = (len >> 1)*lazy[root];
        lazy[lrt] = lazy[rrt] = lazy[root];
        lazy[root] = -1;
    }
}
void build(int l, int r, int root)
{
    lazy[root] = -1;
    if (l == r)
    {
        tree[root] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(root);
}
void update(int l, int r, int root, int lf, int rt,int val)
{
    if (lf <= l && r <= rt)
    {
        tree[root] = (r - l + 1)*val;
        lazy[root] = val;
        return;
    }
    pushdown(root, r - l + 1);
    int mid = (l + r) >> 1;
    if (lf <= mid)update(lson, lf, rt, val);
    if (rt > mid)update(rson, lf, rt, val);
    pushup(root);
}
int  querry(int l, int r, int root, int lf, int rt)
{
    if (lf <= l && r <= rt)
    {
        return tree[root];
    }
    pushdown(root, r - l + 1);
    int mid = (l + r) >> 1;
    int ans = 0;
    if (lf <= mid)ans += querry(lson, lf, rt);
    if (rt > mid)ans += querry(rson, lf, rt);
    return ans;
}
int binarysearch(int a,int b,int num)
{
    int templ = a-1; int tempr = b+1;
    while (tempr -1 > templ)
    {
        int mid = (templ + tempr) >> 1;
        if (querry(0, n - 1, 1, a, mid) < num)templ = mid;
        else tempr = mid;
    }
    return tempr;
}
int main()
{
    T = read();
    while (T--)
    {
        int x, y;
        n = read(), m = read();
        build(0, n - 1, 1);
        while (m--)
        {
            op = read(); x = read(), y = read();
            if (op == 1)
            {
                int temp = querry(0, n - 1, 1, x, n - 1);
                int ansl = binarysearch(x, n - 1, 1);
                int ansr = binarysearch(x, n - 1, min(temp, y));
                if (ansl == n)printf("Can not put any one.\n");
                else {
                    printf("%d %d\n", ansl, ansr);
                    update(0, n - 1, 1, ansl, ansr, 0);
                }
            }
            if (op == 2)
            {
                int sum = querry(0, n - 1, 1, x, y);
                update(0, n - 1, 1, x, y, 1);
                printf("%d\n", (y-x+1)-sum);
            }
        }
        cout << endl;
    }
    return 0;
}

M

题意:屌丝有屌丝想要约的一段时间,自己安排某个区间刚好放下这一段时间,而对于女神来说,女神与女神之间互相不干扰,不能女生用另外一个女神的时间然而可以用屌丝已经安排好的时间,挤掉屌丝。针对q个询问,是否能安排出来时间。

我这里运用了两颗线段树,实际代码可能更短,分别维护屌丝树和女神树,其他的都是基本操作,代码略长而已。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
    char ch = getchar(); int x = 0, f = 1;
    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;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
struct { int l, r,m; }dstree[N<<2],nstree[N<<2];
int dslazy[N << 2],nslazy[N<<2];
int CASE,t,n;
void dspushup(int root,int len)
{
    dstree[root].l = dstree[root << 1].l;
    dstree[root].r = dstree[root << 1 | 1].r;
    dstree[root].m = max(dstree[lrt].m, dstree[rrt].m);
    if (dstree[lrt].l == (len-(len>>1)))dstree[root].l += dstree[rrt].l;
    if (dstree[rrt].r == (len>>1))dstree[root].r += dstree[lrt].r;
    dstree[root].m = max(dstree[root].m, dstree[lrt].r + dstree[rrt].l);
}
void nspushup(int root,int len)
{
    nstree[root].l = nstree[lrt].l;
    nstree[root].r = nstree[rrt].r;
    nstree[root].m = max(nstree[lrt].m, nstree[rrt].m);
    if (nstree[lrt].l == (len - (len >> 1)))nstree[root].l += nstree[rrt].l;
    if (nstree[rrt].r == (len >> 1))nstree[root].r += nstree[lrt].r;
    nstree[root].m = max(nstree[root].m, nstree[lrt].r + nstree[rrt].l);
}
void dspushdown(int root, int len)
{
    if (dslazy[root] == -1)return;
    if (dslazy[root] ==1)
    {
        dstree[lrt].l = dstree[lrt].r=dstree[lrt].m=(len - (len >> 1));
        dstree[rrt].r = dstree[rrt].l = dstree[rrt].m = (len >> 1);
        dslazy[lrt] = dslazy[root];
        dslazy[rrt] = dslazy[root];
        dslazy[root] = -1;
    }
    else
    {
        dstree[lrt].l = dstree[lrt].r = dstree[lrt].m = 0;
        dstree[rrt].l = dstree[rrt].r = dstree[rrt].m = 0;
        dslazy[lrt] = dslazy[root];
        dslazy[rrt] = dslazy[root];
        dslazy[root] = -1;
    }
}
void nspushdown(int root, int len)
{
    if (nslazy[root] == -1)return;
    if (nslazy[root] == 1)
    {
        nstree[lrt].l = nstree[lrt].r = nstree[lrt].m = (len - (len >> 1));
        nstree[rrt].r = nstree[rrt].l = nstree[rrt].m = (len >> 1);
        nslazy[lrt] = nslazy[root];
        nslazy[rrt] = nslazy[root];
        nslazy[root] = -1;
    }
    else
    {
        nstree[lrt].l = nstree[lrt].r = nstree[lrt].m = 0;
        nstree[rrt].l = nstree[rrt].r = nstree[rrt].m = 0;
        nslazy[lrt] = nslazy[root];
        nslazy[rrt] = nslazy[root];
        nslazy[root] = -1;
    }
}
void build(int l, int r, int root)
{
    dslazy[root] = nslazy[root] = -1;
    if (l == r)
    {
        dstree[root].l = nstree[root].l = 1;
        dstree[root].r = nstree[root].r = 1;
        dstree[root].m = nstree[root].m = 1;
        return;
    }
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
    dspushup(root, r - l + 1);
    nspushup(root, r - l + 1);
}
void dsupdate(int l, int r, int root, int lf, int rt, int val)
{
    if (lf <= l && r <= rt)
    {
        if (val)
        {
            dstree[root].l = dstree[root].r = dstree[root].m = (r - l + 1);
            dslazy[root] = val;
        }
        else
        {
            dstree[root].l = dstree[root].r = dstree[root].m = 0;
            dslazy[root] = val;
        }
        return;
    }
    dspushdown(root, r - l + 1);
    int mid = (l + r) >> 1;
    if (lf <= mid)dsupdate(lson, lf, rt, val);
    if (rt > mid)dsupdate(rson, lf, rt, val);
    dspushup(root, r - l + 1);
}
void nsupdate(int l, int r, int root, int lf, int rt, int val)
{
    if (lf <= l && r <= rt)
    {
        if (val)
        {
            nstree[root].l = nstree[root].r = nstree[root].m = (r - l + 1);
            nslazy[root] = val;
        }
        else
        {
            nstree[root].l = nstree[root].r = nstree[root].m = 0;
            nslazy[root] = val;
        }
        return;
    }
    nspushdown(root, r - l + 1);
    int mid = (l + r) >> 1;
    if (lf <= mid)nsupdate(lson, lf, rt, val);
    if (rt > mid)nsupdate(rson, lf, rt, val);
    nspushup(root, r - l + 1);
}
int dsquerry(int l, int r, int root, int len)
{
    if (l == r)return l;
    dspushdown(root, r - l + 1);
    int mid = (l + r) >> 1;
    if (dstree[lrt].m >= len)return dsquerry(lson, len);
    else if (dstree[lrt].r + dstree[rrt].l >= len)return mid - dstree[lrt].r + 1;
    else if (dstree[rrt].m >= len)return dsquerry(rson, len);
}
int nsquerry(int l, int r, int root, int len)
{
    if (l == r)return l;
    nspushdown(root, r - l + 1);
    int mid = (l + r) >> 1;
    if (nstree[lrt].m >= len)return nsquerry(lson, len);
    else if (nstree[lrt].r + nstree[rrt].l >= len)return mid - nstree[lrt].r + 1;
    else if (nstree[rrt].m >= len)return nsquerry(rson, len);
}
int main()
{
    CASE = read();
    upd(p, 1, CASE)
    {
        t = read(), n = read();
        build(1, t, 1);
        int x,y;
        printf("Case %d:\n", p);
        while (n--)
        {
            char s[20];
            scanf("%s", s);
            if (s[0] == 'D')
            {
                x = read();
                if (dstree[1].m >= x)
                {
                    int l = dsquerry(1, t, 1, x);
                    dsupdate(1, t, 1, l, l + x - 1, 0);
                    printf("%d,let's fly\n", l);
                }
                else printf("fly with yourself\n");
            }
            else if(s[0]=='N')
            {
                x = read();
                if (dstree[1].m >= x)
                {
                    int l = dsquerry(1, t, 1, x);
                    dsupdate(1, t, 1, l, l + x - 1, 0);
                    nsupdate(1, t, 1, l, l + x - 1, 0);
                    printf("%d,don't put my gezi\n", l);
                }
                else if (nstree[1].m >= x)
                {
                    int l = nsquerry(1, t, 1, x);
                    dsupdate(1, t, 1, l, l + x - 1, 0);
                    nsupdate(1, t, 1, l, l + x - 1, 0);
                    printf("%d,don't put my gezi\n", l);
                }
                else printf("wait for me\n");
            }
            else
            {
                printf("I am the hope of chinese chengxuyuan!!\n");
                x = read(), y = read();
                dsupdate(1, t, 1, x, y, 1);
                nsupdate(1, t, 1, x, y, 1);
            }
        }
    }
    return 0;
}

kuangbin带你飞--线段树二

原文:https://www.cnblogs.com/LORDXX/p/11556269.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!