牛客网暑期ACM多校训练营(第六场)- I Team Rocket (线段树)

给你n条l到r的线段。
在给你q个询问,每次给你一个x,可以切断线段,问你每次破坏了多少线段。
每次给出的要破坏的数不是单纯的x,而是上一次所有切断线段的编号的乘积和x的异或值,
求出要破坏的值y后,哪一条线段包含y,哪一条线段就被破坏掉。
每次询问输出此次破坏掉了几条线段。
最后还要输出所有线段最早是被第几次操作破坏掉的 | 没有被破坏(输出0)。

维护区间最小值和最大值即可。
并且由于我的写法每次都是跑到叶子结点,所以这些线段也不用排序。
代码里有详细的debug输出。

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
#define lson rt<<1
#define rson rt<<1|1
#define MID int m = (l+r)/2;
struct node
{
    int id,l,r;
} a[maxn];
int L[maxn],R[maxn];
vector<node>V;
void push_up(int rt)
{
    L[rt] = min(L[lson],L[rson]);
    R[rt] = max(R[lson],R[rson]);
}
void build(int rt,int l,int r)
{
    //if(l>r)return;

    if(l==r)
    {
        L[rt] = a[l].l;
        R[rt] = a[l].r;
     //   cout<<"线段树 "<<rt<<" "<<a[l].l<<" "<<a[l].r<<" "<<l<<endl;
        return;
    }
    MID
    build(lson,l,m);
    build(rson,m+1,r);
    push_up(rt);
  //  cout<<"父节点 "<<rt<<" "<<L[rt]<<" "<<R[rt]<<" "<<l<<" "<<r<<endl;
}
int ans[maxn];
void update(int rt,int l,int r,int pos)
{
    if(pos<L[rt]||pos>R[rt])return ;
    if(l==r)
    {
        // cout<<"线段树 "<<rt<<" "<<a[l].l<<" "<<a[l].r<<" "<<l<<endl;
        V.push_back(a[l]);
        L[rt] = inf;
        R[rt]  =-inf;
        return ;
    }
    MID
    update(lson,l,m,pos);
    update(rson,m+1,r,pos);
    push_up(rt);
     //cout<<"父节点 "<<rt<<" "<<L[rt]<<" "<<R[rt]<<" "<<l<<" "<<r<<endl;
}
int main()
{
    int T;
    cin>>T;
    int cs = 0;
    while(T--)
    {
        printf("Case #%d:\n",++cs);
        int n,q;
        cin>>n>>q;
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].id = i;
            ans[i] = 0;

        }
        build(1,1,n);
        long long  res = 0;
        for(int i=1; i<=q; i++)
        {
            V.clear();
            int y ;
            scanf("%d",&y);
            long long yy = res^y;
          //  yy = y;
            update(1,1,n,yy);
            printf("%d\n",(int )V.size());
            if(V.size()==0)res = 0;
            else

            {
                res = 1;
                for(node j:V)
                {
                    res=(res*j.id)%mod;
                    ans[j.id] = i;
                }
            }

        }
        int top = 1;
        for(int i=1; i<=n; i++)
        {

            if(top)top =0;
            else printf(" ");
            printf("%d",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/axuhongbo/article/details/81699877