2019CCPC network trials array (weights tree line)

2019CCPC network trials 1002 HDU6703

 

Subject to the effect:

T a sample. Give you an array of length n a, 1≤a [i] ≤n, a [i] are different. m operations. ans 0 initially. There are two modes of operation:

Action 1: Here you are t1. pos = t1 ^ ans. The number of array subscript pos numerical + 1e7;

Action 2: Give your t2, t3. r = t2 ^ ans, k = t3 ^ ans. ** The number of different output array subscript of 1 ~ r ** and ** K ** is not less than the minimum number. Update ans.

data range:

1≤T≤10,1≤n≤1e5,1≤m≤1e5,1≤a [i] ≤n, a [ i] are different, . 1 P O S n-, 1≤r≤n,. 1 ≤k≤n.

n510,000,m510,000。

 

Up questions after the game.

 

Here copy the standard solution to a problem:

Because unique values ​​in the array, and in the range of 1 to n, and r and k are asked in the range of 1 to n. So for any operated one modified value will not be an answer to the query, the query results are bound to k in the range of n + 1. Because not been modified values ​​are unique, so you can build tree line weights, weight maintenance value in the range where the subscript maximum. The query is converted to the value of k is not smaller than the inside, more than the subscript r is the number of minimum weight. How it handles inquiries, a more violent solution is to directly ask the tree line segment weights in the range of k to n + 1, the first index exceeds the weight r is. But the complexity of the card may be, you need to cut branches. Plus an additional judgment on it, that is, after the completion of recursive query is greater than r subscript left subtree memory does not exist, and if not, then take a look at the subject in the right subtree is greater than the maximum value of r. If not greater than r, then you do not have to enter a query in the right subtree, otherwise the answer must be in the right subtree. Before entering the left subtree also use the same judgment the conditions to determine whether it is necessary to enter the left subtree This ensures that a single query complexity is O (log n) of. For an operation, this is equivalent to a weight modification index is infinite. Operational complexity is also O (log n) of the. In summary, the line algorithm to obtain a complexity of O (m * log n) can be quickly by this problem. 

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+50;
const int inf=0x3f3f3f3f;
struct P{
    int l,r,id;
}tree[maxn<<2];
void build(int l,int r,int k)
{
    tree[k].l=l;tree[k].r=r;    
    if(tree[k].l==tree[k].r)
    {
        tree[k].id=0;        
        return ;
    }    
    int mid=(tree[k].l+tree[k].r)/2;
    build(l,mid,k*2);
    build(mid+1,r,k*2+1);
    tree[k].id=0;
}
void add(int x,int id,int k)
{
    if(tree[k].l==tree[k].r)
    {
        tree[k].id=id;return;
    }
    int mid=(tree[k].l+tree[k].r)/2;
    if(x<=mid)add(x,id,k*2);
    else add(x,id,k*2+1);
    tree[k].id=max(tree[k*2].id,tree[k*2+1].id);
}
int find(int l,int r,int k,int minid)
{
    if(tree[k].l==tree[k].r)
    {
        if(tree[k].id>minid)return l;
        return inf;
    }
    if(tree[k].id<=minid)return inf;
    int mid=(tree[k].l+tree[k].r)/2;
    int id1=tree[k*2].id,id2=tree[k*2+1].id;
    if(r<=mid)
    {
        if(id1<=minid)return inf;
        return find(l,r,k*2,minid);
    }
    if(l>mid)
    {
        if(id2<=minid)return inf;
        return find(l,r,k*2+1,minid);
    }
    int ans1=inf,ans2=inf,ans=inf;
    if(id1>minid)ans1=find(l,mid,k*2,minid);
    if(id2>minid&&ans1==inf)ans2=find(mid+1,r,k*2+1,minid);
    ans=min(ans1,ans2);
    return ans;
}
/*void f(int l,int r,int k)
{
    printf("##l:%d ##r:%d##id:%d\n",tree[k].l,tree[k].r,tree[k].id);
    if(tree[k].l==tree[k].r)return;
    int mid=(tree[k].l+tree[k].r)/2;
    f(l,mid,k*2);
    f(l,mid,k*2+1);
}*/
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m,op,t1,t2,t3,i,a[maxn],ans=0;
        scanf("%d%d",&n,&m);
        build(1,n,1);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            add(a[i],i,1);
        }
        //f(1,n,1);
        for(i=1;i<=m;i++)
        {
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d",&t1);
                add(a[t1^ans],inf,1);
                //f(1,n,1);
                continue;
            }
            scanf("%d%d",&t2,&t3);
            t2^=ans;t3^=ans;
            ans=find(t3,n,1,t2);
            //printf("@@r:%d k:%d@@ans:",t2,t3);
            if(ans!=inf)printf("%d\n",ans);
            else{
                ans=n+1;
                printf("%d\n",ans);
            }
        }
        //puts("############");
    }
}

 

Guess you like

Origin www.cnblogs.com/kkkek/p/11441193.html