• 【BZOJ 4103】 4103: [Thu Summer Camp 2015]异或运算 (可持久化Trie)


    4103: [Thu Summer Camp 2015]异或运算

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 474  Solved: 258

    Description

    给定长度为n的数列X={x1,x2,...,xn}和长度为m的数列Y={y1,y2,...,ym},令矩阵A中第i行第j列的值Aij=xi xor  yj,每次询问给定矩形区域i∈[u,d],j∈[l,r],找出第k大的Aij。

    Input

    第一行包含两个正整数n,m,分别表示两个数列的长度

    第二行包含n个非负整数xi
    第三行包含m个非负整数yj
    第四行包含一个正整数p,表示询问次数
    随后p行,每行均包含5个正整数,用来描述一次询问,每行包含五个正整数u,d,l,r,k,含义如题意所述。

    Output

    共p行,每行包含一个非负整数,表示此次询问的答案。

    Sample Input

    3 3
    1 2 4
    7 6 5
    3
    1 2 1 2 2
    1 2 1 3 4
    2 3 2 3 4

    Sample Output

    6
    5
    1

    HINT

     对于100%的数据,0<=Xi,Yj<2^31,



    1<=u<=d<=n<=1000,


    1<=l<=r<=m<=300000,


    1<=k<=(d-u+1)*(r-l+1),


    1<=p<=500

    Source

    【分析】

      要膜一膜Po姐:

      好了,这个是。。。异或运算。每一位的运算都和下一位无关的。

      当n=1,你只要根据m个数建一个可持久化TRIE。然后询问的时候就试着填1看看足不足k什么的。

      跟平时不一样的是,现在你是手上拿着个a1之后询问的,你只要每次看一看a1这一位是什么,然后判断填1还是0,如果a1这一位是1就要0、1互换一下嘛。。

      然后n不等于1,其实也很小,相当于1000个TRIE?当然是不用建1000个TRIE的【你也建不了吧?

      只是你现在手上拿着1000个ai,一起询问什么的。。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 1010
      8 #define Maxm 300010
      9 #define Maxd 30
     10 
     11 int a[Maxn];
     12 
     13 int rt[Maxm],tot=0;
     14 struct node {int lc,rc,cnt;}tr[Maxm*32];
     15 
     16 void add(int id,int x)
     17 {
     18     rt[id]=++tot;int y=rt[id-1];
     19     int nw=rt[id];
     20     for(int i=Maxd;i>=0;i--)
     21     {
     22         int ind=x>>i;x&=(1<<i)-1;
     23         if(!ind)
     24         {
     25             tr[nw].lc=++tot;
     26             tr[tot].cnt=tr[tr[y].lc].cnt+1;
     27             tr[nw].rc=tr[y].rc;
     28             nw=tr[nw].lc;y=tr[y].lc;
     29         }
     30         else
     31         {
     32             tr[nw].rc=++tot;
     33             tr[tot].cnt=tr[tr[y].rc].cnt+1;
     34             tr[nw].lc=tr[y].lc;
     35             nw=tr[nw].rc;y=tr[y].rc;
     36         }
     37     }
     38 }
     39 
     40 int nl[Maxn],nr[Maxn];
     41 int query(int ll,int rr,int l,int r,int k)
     42 {
     43     int ans=0;
     44     // l=rt[l-1];r=rt[r];
     45     for(int i=ll;i<=rr;i++) nl[i]=rt[l-1],nr[i]=rt[r];
     46     for(int i=Maxd;i>=0;i--)
     47     {
     48         int x=0;
     49         for(int j=ll;j<=rr;j++)
     50         {
     51             int y=a[j]&(1<<i);y>>=i;
     52             if(y==0) x+=tr[tr[nr[j]].lc].cnt-tr[tr[nl[j]].lc].cnt;
     53             else x+=tr[tr[nr[j]].rc].cnt-tr[tr[nl[j]].rc].cnt;
     54         }
     55         if(x>=k)
     56         {
     57             l=tr[l].lc;r=tr[r].lc;
     58             for(int j=ll;j<=rr;j++)
     59             {
     60                 int y=a[j]&(1<<i);y>>=i;
     61                 if(y==0) nl[j]=tr[nl[j]].lc,nr[j]=tr[nr[j]].lc;
     62                 else nl[j]=tr[nl[j]].rc,nr[j]=tr[nr[j]].rc;
     63             }
     64         }
     65         else
     66         {
     67             k-=x;
     68             ans|=1<<i;
     69             for(int j=ll;j<=rr;j++)
     70             {
     71                 int y=a[j]&(1<<i);y>>=i;
     72                 if(y==0) nl[j]=tr[nl[j]].rc,nr[j]=tr[nr[j]].rc;
     73                 else nl[j]=tr[nl[j]].lc,nr[j]=tr[nr[j]].lc;
     74             }
     75         }
     76     }
     77     return ans;
     78 }
     79 
     80 int main()
     81 {
     82     int n,m;
     83     scanf("%d%d",&n,&m);
     84     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
     85     for(int j=1;j<=m;j++)
     86     {
     87         int b;
     88         scanf("%d",&b);
     89         add(j,b);
     90     }
     91     int q;
     92     scanf("%d",&q);
     93     for(int i=1;i<=q;i++)
     94     {
     95         int ll,rr,l,r,k;
     96         scanf("%d%d%d%d%d",&ll,&rr,&l,&r,&k);
     97         k=(rr-ll+1)*(r-l+1)-k+1;
     98         printf("%d
    ",query(ll,rr,l,r,k));
     99     }
    100     return 0;
    101 }
    View Code

    最近已经RE至死。。。

    数组开少了2。。。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 1010
      8 #define Maxm 300010
      9 #define Maxd 30
     10 
     11 int a[Maxn];
     12 
     13 int rt[Maxm],tot=0;
     14 struct node {int lc,rc,cnt;}tr[Maxm*32];
     15 
     16 void add(int id,int x)
     17 {
     18     rt[id]=++tot;int y=rt[id-1];
     19     int nw=rt[id];
     20     for(int i=Maxd;i>=0;i--)
     21     {
     22         int ind=x>>i;x&=(1<<i)-1;
     23         if(!ind)
     24         {
     25             tr[nw].lc=++tot;
     26             tr[tot].cnt=tr[tr[y].lc].cnt+1;
     27             tr[nw].rc=tr[y].rc;
     28             nw=tr[nw].lc;y=tr[y].lc;
     29         }
     30         else
     31         {
     32             tr[nw].rc=++tot;
     33             tr[tot].cnt=tr[tr[y].rc].cnt+1;
     34             tr[nw].lc=tr[y].lc;
     35             nw=tr[nw].rc;y=tr[y].rc;
     36         }
     37     }
     38 }
     39 
     40 int nl[Maxn],nr[Maxn];
     41 int query(int ll,int rr,int l,int r,int k)
     42 {
     43     int ans=0;
     44     // l=rt[l-1];r=rt[r];
     45     for(int i=ll;i<=rr;i++) nl[i]=rt[l-1],nr[i]=rt[r];
     46     for(int i=Maxd;i>=0;i--)
     47     {
     48         int x=0;
     49         for(int j=ll;j<=rr;j++)
     50         {
     51             int y=a[j]&(1<<i);y>>=i;
     52             if(y==0) x+=tr[tr[nr[j]].lc].cnt-tr[tr[nl[j]].lc].cnt;
     53             else x+=tr[tr[nr[j]].rc].cnt-tr[tr[nl[j]].rc].cnt;
     54         }
     55         if(x>=k)
     56         {
     57             l=tr[l].lc;r=tr[r].lc;
     58             for(int j=ll;j<=rr;j++)
     59             {
     60                 int y=a[j]&(1<<i);y>>=i;
     61                 if(y==0) nl[j]=tr[nl[j]].lc,nr[j]=tr[nr[j]].lc;
     62                 else nl[j]=tr[nl[j]].rc,nr[j]=tr[nr[j]].rc;
     63             }
     64         }
     65         else
     66         {
     67             k-=x;
     68             ans|=1<<i;
     69             for(int j=ll;j<=rr;j++)
     70             {
     71                 int y=a[j]&(1<<i);y>>=i;
     72                 if(y==0) nl[j]=tr[nl[j]].rc,nr[j]=tr[nr[j]].rc;
     73                 else nl[j]=tr[nl[j]].lc,nr[j]=tr[nr[j]].lc;
     74             }
     75         }
     76     }
     77     return ans;
     78 }
     79 
     80 int main()
     81 {
     82     int n,m;
     83     scanf("%d%d",&n,&m);
     84     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
     85     for(int j=1;j<=m;j++)
     86     {
     87         int b;
     88         scanf("%d",&b);
     89         add(j,b);
     90     }
     91     int q;
     92     scanf("%d",&q);
     93     for(int i=1;i<=q;i++)
     94     {
     95         int ll,rr,l,r,k;
     96         scanf("%d%d%d%d%d",&ll,&rr,&l,&r,&k);
     97         k=(rr-ll+1)*(r-l+1)-k+1;
     98         printf("%d
    ",query(ll,rr,l,r,k));
     99     }
    100     return 0;
    101 }
    View Code

    2017-04-08 14:47:45

  • 相关阅读:
    BZOJ3669
    HDU3726
    BZOJ3282
    BZOJ2843
    Link/cut Tree
    Codeforces396A
    LOJ6277~6285 数列分块入门
    Codeforces446C
    Codeforces475D
    Codeforces103D
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6681856.html
Copyright © 2020-2023  润新知