首页 > 其他分享 >G73 线段树+线性基合并 P5607 [Ynoi2013] 无力回天 NOI2017

G73 线段树+线性基合并 P5607 [Ynoi2013] 无力回天 NOI2017

时间:2024-07-29 15:50:53浏览次数:7  
标签:P5607 return int void Ynoi2013 tr NOI2017

视频链接:G73 线段树+线性基合并 P5607 [Ynoi2013] 无力回天 NOI2017_哔哩哔哩_bilibili

 

 

 

P5607 [Ynoi2013] 无力回天 NOI2017 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 线段树+线性基合并 O(n*logn*logv*logv)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

#define ls (u<<1)
#define rs (u<<1|1)
#define mid (l+r>>1)
const int N=50005;
int a[N],n,m;
struct Tree{
  int p[31]; //区间线性基
  int s;     //区间异或和
  void clear(){memset(p,0,sizeof p);}
  void insert(int x){ //插入基
    for(int i=30;i>=0;--i)
      if(x>>i&1){
        if(!p[i]){p[i]=x;break;}
        x^=p[i];
      }
  }
}tr[N<<2]; //节点

Tree merge(Tree a,Tree b){ //合并基
  Tree c;
  c.clear(); //清空基数组
  for(int i=30;i>=0;--i)
    if(a.p[i]) c.p[i]=a.p[i];
    else if(b.p[i]) c.p[i]=b.p[i];
  for(int i=30;i>=0;--i) 
    if(a.p[i]&&b.p[i]) c.insert(b.p[i]);
  c.s=a.s^b.s;
  return c;
}
void build(int u,int l,int r){ //建树
  if(l==r){tr[u].insert(tr[u].s=a[l]);return;}
  build(ls,l,mid);
  build(rs,mid+1,r);
  tr[u]=merge(tr[ls],tr[rs]);
}
void change(int u,int l,int r,int pos,int x){ //点修
  if(l==r){
    tr[u].clear(); //清空基数组
    tr[u].insert(tr[u].s^=x);
    return;
  }
  if(pos<=mid) change(ls,l,mid,pos,x);
  else change(rs,mid+1,r,pos,x);
  tr[u]=merge(tr[ls],tr[rs]);
}
int sum(int u,int l,int r,int pos){ //前缀和
  if(l==r) return tr[u].s;
  if(pos<=mid) return sum(ls,l,mid,pos);
  else return sum(rs,mid+1,r,pos)^tr[ls].s;
}
Tree ask(int u,int l,int r,int L,int R){ //区查
  if(L<=l&&r<=R) return tr[u];
  if(L>mid) return ask(rs,mid+1,r,L,R);
  if(R<=mid) return ask(ls,l,mid,L,R);
  return merge(ask(ls,l,mid,L,R),ask(rs,mid+1,r,L,R));
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;++i) scanf("%d",&a[i]);
  for(int i=n-1;i;--i) a[i+1]^=a[i]; //转成差分数组
  build(1,1,n);
  for(int opt,l,r,v;m--;){
    scanf("%d%d%d%d",&opt,&l,&r,&v);
    if(opt==1){
      change(1,1,n,l,v); //点修l
      if(r<n) change(1,1,n,r+1,v); //点修r+1
    } 
    else{
      int s=sum(1,1,n,l); //求a[l]
      if(l==r) printf("%d\n",max(v,v^s));
      else{
        Tree t=ask(1,1,n,l+1,r); //求b[l+1...r]
        t.insert(s); //插入a[l]
        for(int i=30;i>=0;--i) v=max(v,v^t.p[i]);
        printf("%d\n",v);
      }
    }
  }
}

 

标签:P5607,return,int,void,Ynoi2013,tr,NOI2017
From: https://www.cnblogs.com/dx123/p/18328599

相关文章

  • P3825 [NOI2017] 游戏
    题目大意有四种类型的比赛\(x,a,b,c\),三种赛车(\(A,B,C\))。其中\(x\)的数量为\(d\)。\(x\)表示三种赛车都可以选,\(a\)表示\(A\)种不能选,\(b\)表示\(B\)种不能选,\(c\)表示\(C\)种不能选。现在要比\(n\)场,有\(m\)个限制形如:\(p,f,q,t\)表示如果第\(p\)......
  • 5034. 【NOI2017模拟3.28】B —— 矩阵树定理和拉格朗日插值的结合
    题目大意给你一棵\(n\)(\(n\le50\))个点的树,可以进行不超过\(k\)次操作,每次断掉一条边,再连上一条边,要求树一直是树,求一共有多少种树的形态。思路把题意转换为对于一个\(n\)个点的完全图,是树边的话权值是\(1\),否则是\(x\)。跑一遍矩阵树定理,矩阵树定理求的是一个图所有生......
  • P5610 [Ynoi2013] 大学
    [Ynoi2013]大学-洛谷傻逼卡常题发现自己基础数据结构用的还不是很熟练,并没有想到一开始的\(set\)做法,更不用提后面的并查集优化了首先每个数最多被进行\(O(\logA)\)次有效除法,如果我们找到区间中哪些数要被除后直接暴力用树状数组单点修改,可以做到\(O(n\logn......
  • P5607 [Ynoi2013] 无力回天 NOI2017
    [Ynoi2013]无力回天NOI2017-洛谷看到题目可以想到线性基线性基可以做到\(O(\logA)\)加入,\(O(\logA)\)查询,\(O(\log^2A)\)合并考虑直接暴力的用线段树维护每个节点的线性基,可以做到\(O(n\logn\log^2A)\)但有区间修改?差分转单点修,发现线性基\(a_{[l......
  • NOI2017 蔬菜
    传送门NOI的题果然是非常的难且有意思。还有就是推荐一下command_block的题解。这题的题意比较难。题意:有\(n\)种菜,初始每种菜有\(c_i\)个,单价\(a_i\),如果不出售每天会变质\(x_i\)棵。第一次卖这种菜会获得\(s_i\)的奖励。每天至多卖\(m\)个菜。给出\(q\)次询......
  • [Ynoi2013] 大学
    非常好之\(\texttt{lxl}\)使我的代码旋转。看到这个题,第一反应显然是如果我们能够每次确切的找到要除的数,然后用树状数组进行单点修改,那么就可以达到\(\mathcal{O}(n\logV\logn)\)的复杂度。那么接下来就是考虑如何去找到能除的数。首先,我们不难想到对于每个权值\(v\)......
  • P5609 [Ynoi2013] 对数据结构的爱
    题面传送门好像搞了个神秘做法。考虑离线扫描线,用一个fhq-Treap维护所有的询问现在长什么样,然后每次操作就整体加\(A_i\),\(\geqp\)的减去\(p\),这个可以分裂之后打整体标记,然后用那个值域相交的fhq-Treap合并实现。然后你发现这样就过了。构造一下卡不掉,于是考虑给这个......
  • [AH2017HNOI2017] 礼物(fft)
    [AH2017/HNOI2017]礼物(fft)题目描述我的室友最近喜欢上了一个可爱的小女生。马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她。每个手环上各有\(n\)个装饰物,并且每个装饰物都有一定的亮度。但是在她生日的前一天,我的室友突然发现他好像拿错了一个手环,而且......
  • #分块,二分#洛谷 5356 [Ynoi2017] 由乃打扑克
    题目支持区间加和区间查询第\(k\)小分析分块之后给每个整块排序,这样修改的时候整块打标记,散块直接分开把需要加的部分暴力加之后归并,就是\(O(\sqrt{n})\)的查询的话,如果只有散块直接归并出结果,否则二分答案,加上小块合并成的整块,相当于是整体二分,就是\(O(\sqrt{n}\log{a_......
  • HNOI2017影魔题解
    HNOI2017影魔对于两种贡献,都只用考虑左边第一个比自己大的,和右边第一个比自己大的数,分别记为\(l_i、r_i\)对于询问一,每个数对\((l_i,r_i)\)构成全部情况对于询问二,可以拆分成\(x=l_i\)时,\(y\in[i+1,r_i-1]\),以及\(y=r_i\)时,\(x\in[l_i+1,i-1]\)我们考虑用扫描线......