zoukankan      html  css  js  c++  java
  • [Luogu5105]不强制在线的动态快速排序

    首先集合去重不影响答案,然后打表易得连续自然数平方差异或前缀和的规律,于是问题就变为在线维护区间求并同时更新答案,set记录所有区间,每次暴力插入删除即可。由于每个区间至多只会插入删除一次,故均摊复杂度$O(nlog n)$

     1 #include<set>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=300010;
     9 int Q,op,l,r;
    10 ll ans;
    11 struct P{ int l,r; };
    12 bool operator <(const P &a,const P &b){ return a.l<b.l; }
    13 set<P>S;
    14 
    15 ll D(int n){
    16     n=(n+1)/2;
    17     if (n%4==1) return 2*n-1;
    18     if (n%4==2) return 2;
    19     if (n%4==3) return 2*n+1;
    20     return 0;
    21 }
    22 
    23 ll calc(int l,int r){ if (l==r) return 0; else return D(r*2-1)^D(l*2-1); }
    24 
    25 ll get(set<P>::iterator it){
    26     int l=it->l,r=it->r,u=-1,v=-1; ll res=calc(l,r);
    27     it++; if (it!=S.end()) res^=1ll*((it->l)+r)*((it->l)-r),u=it->l;
    28     it--; if (it!=S.begin()) it--,res^=1ll*(l+(it->r))*(l-(it->r)),v=it->r;
    29     if (~u && ~v) res^=1ll*(u+v)*(u-v);
    30     return res;
    31 }
    32 
    33 void work(int l,int r){
    34     if (S.empty()) { ans=calc(l,r); S.insert((P){l,r}); return; }
    35     set<P>::iterator it=S.lower_bound((P){l,r});
    36     while (it!=S.end() && it->l<=r)
    37         l=min(l,it->l),r=max(r,it->r),ans^=get(it),S.erase(it),it=S.lower_bound((P){l,r});
    38     if (it!=S.begin()){
    39         it--;
    40         while (it->r>=l){
    41             l=min(l,it->l); r=max(r,it->r); ans^=get(it); S.erase(it);
    42             it=S.lower_bound((P){l,r});
    43             if (it==S.begin()) break; else it--;
    44         }
    45     }
    46     it=S.insert((P){l,r}).first; ans^=get(it);
    47     //for (it=S.begin(); it!=S.end(); it++) printf("%d %d
    ",it->l,it->r); puts("");
    48 }
    49 
    50 int main(){
    51     for (scanf("%d",&Q); Q--; ){
    52         scanf("%d",&op);
    53         if (op==1) scanf("%d%d",&l,&r),work(l,r); else printf("%lld
    ",ans);
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    直接初始化和复制初始化
    C++ 内连接与外连接 (转)
    mysql-Innodb事务隔离级别-repeatable read详解(转)
    Linux操作系统多线程信号总结
    Keil MDK 5.14 仿真时System Viewer菜单显示空白和Peripherals菜单无外设寄存器
    转载傅里叶级数和傅里叶变换的理解 https://www.cnblogs.com/h2zZhou/p/8405717.html
    SPI总线的原理与Verilog实现
    SD 模拟sip 读写子程序
    SD卡 模拟SPI总线控制流程
    SD卡spi读写流程
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10225704.html
Copyright © 2011-2022 走看看