题解:

原来动态开点平衡树是O(n)空间的。。

只需要在split的查找和出来之后动态开点就可以了

这题的结论是2^(b[a[i]+1]>b[a[i+1]+1]的个数)

前60分是普通的平衡树操作完之后再算

满分是动态开点平衡树

对于一个点内部的统计一下,边界上的特判一下

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define dep(i,t,h) for (int i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
#define ll long long
#define mid ((h+t)>>1)
#define mep(x,y) memcpy(x,y,sizeof(y))
namespace IO
{
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T>void read(T &x)
{
rint f=,c;while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
char sr[<<],z[]; int C=-,Z;
template<class T>void wer(T x)
{
if (x<) sr[++C]='-',x=-x;
while (z[++Z]=x%+,x/=);
while (sr[++C]=z[Z],--Z);
}
IL void wer1() {sr[++C]=' ';}
IL void wer2() {sr[++C]='\n';}
template<class T>IL void maxa(T &x,T y) { if (x<y) x=y;}
template<class T>IL void mina(T &x,T y) { if (x>y) x=y;}
template<class T>IL T MAX(T x,T y){ return x>y?x:y;}
template<class T>IL T MIN(T x,T y){ return x<y?x:y;}
}
using namespace IO;
const int N=9e5;
int a[N],b[N],xl[N],cnt,dy[N],d[N],tmp;
const int mo=1e9+;
struct re{
int a,b,kk,d;
}c[N],f[N],p[N],c1[N];
int nq;
struct phs{
int fa[N],rs[N],ls[N],num[N],o[N],v[N],cnt,cnt3;
bool rev[N],t[N];
IL void updata(int x)
{
num[x]=num[ls[x]]+num[rs[x]]+o[x];
}
IL void down(int x)
{
if (rev[x])
{
swap(ls[ls[x]],rs[ls[x]]);
swap(ls[rs[x]],rs[rs[x]]);
rev[ls[x]]^=; rev[rs[x]]^=;
t[ls[x]]^=; t[rs[x]]^=;
rev[x]=;
}
}
void rotate(int x,int y)
{
int f1=fa[x];
if (y==)
{
rs[f1]=ls[x];
if (ls[x]) fa[ls[x]]=f1;
} else
{
ls[f1]=rs[x];
if (rs[x]) fa[rs[x]]=f1;
}
fa[x]=fa[f1];
if (fa[f1])
{
if (ls[fa[f1]]==f1) ls[fa[f1]]=x; else rs[fa[f1]]=x;
}
fa[f1]=x;
if (y==) ls[x]=f1; else rs[x]=f1;
updata(f1); updata(x);
}
void dfs(int x)
{
if (fa[x]) dfs(fa[x]);
down(x);
}
IL void splay(int x,int y)
{
dfs(x);
int f1=fa[x];
while (f1!=y)
{
if (fa[f1]==y)
if (ls[f1]==x) rotate(x,); else rotate(x,);
else
if (ls[fa[f1]]==f1)
if (ls[f1]==x) rotate(f1,),rotate(x,);
else rotate(x,),rotate(x,);
else if (rs[f1]==x) rotate(f1,),rotate(x,);
else rotate(x,),rotate(x,);
f1=fa[x];
}
}
IL int sc(int x,int y)
{
if (t[x])
{
o[++nq]=y; num[nq]=y; fa[nq]=x; v[nq]=v[x];
ls[nq]=ls[x]; o[x]-=y;
v[x]+=y; ls[x]=nq; t[nq]=t[x];
} else
{
o[++nq]=y; num[nq]=y; fa[nq]=x; v[nq]=v[x]+o[x]-y;
ls[nq]=ls[x]; o[x]-=y;
ls[x]=nq; t[nq]=t[x];
}
if (ls[nq]) fa[ls[nq]]=nq;
num[nq]+=num[ls[nq]];
return nq;
}
IL int search(int y)
{
splay(,);
int x=;
while ()
{
down(x);
if (num[ls[x]]+o[x]>=y&&num[ls[x]]<y)
{
if (num[ls[x]]+o[x]==y) return(x);
return sc(x,y-num[ls[x]]);
}
if (num[ls[x]]+o[x]>y) x=ls[x];
else y-=num[ls[x]]+o[x],x=rs[x];
}
}
IL int split(int x,int y)
{
int k1=search(x),k2=search(y+);
splay(k1,);
splay(k2,k1);
if (o[k2]!=)
sc(k2,o[k2]-);
return ls[k2];
}
IL void reverse(int x,int y)
{
int k=split(x,y);
rev[k]^=; swap(ls[k],rs[k]); t[k]^=;
}
IL void change(int x,int y)
{
int k=split(x,y);;
int now=fa[k];
ls[now]=; fa[k]=; splay(now,);
now=search();
splay(now,); down(now); down();
rs[]=k; fa[k]=; splay(k,);
}
void dfs2(int x)
{
down(x);
if (ls[x]) dfs2(ls[x]);
// a[++cnt]=v[x];
c[++cnt]=(re){v[x],o[x],t[x],cnt3+};
cnt3+=o[x];
if (rs[x]) dfs2(rs[x]);
}
}S;
bool cmp(re x,re y)
{
return x.a<y.a;
}
IL int pos(int x)
{
if (x>tmp) return();
int h=,t=S.cnt-;
while (h<t)
{
if (f[mid].a+f[mid].b->=x) t=mid;
else h=mid+;
}
if (f[h].kk) return f[h].d+x-f[h].a;
else return f[h].d+f[h].b--(x-f[h].a);
}
IL int pos2(int x)
{
if (c[x].kk) return c[x].a;
else return c[x].a+c[x].b-;
}
IL int fsp(ll x,int y)
{
ll ans=;
while (y)
{
if (y&) ans=ans*x%mo;
x=x*x%mo; y>>=;
}
return ans;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int n,m;
read(n); read(m);
tmp=n;
int cnt=;
nq=;
S.rs[]=; S.rs[]=; S.fa[]=; S.fa[]=; S.t[]=;
S.o[]=; S.v[]=; S.o[]=n; S.v[]=; S.o[]=; S.v[]=n+;
S.splay(,);
rep(i,,m)
{
int kk,x,y;
read(kk); read(x); read(y);
if (kk==) S.change(x,y);
else S.reverse(x,y);
}
S.splay(,);
S.dfs2();
int l=S.cnt;
rep(i,,l-) f[i]=c[i+];
sort(f+,f+l-+,cmp);
cnt=;
rep(i,,l-)
{
if (c[i].b>=) cnt+=c[i].b-;
if (c[i].kk)
{
if (c[i].b>=&&i!=(l-))
{
int k1=c[i].a+c[i].b-,k2=pos2(i+);
if (pos(k1+)<pos(k2+)) cnt++;
}
if (c[i].b>=)
{
int k1=c[i].a+c[i].b-,k2=c[i].a+c[i].b-;
if (pos(k1+)<pos(k2+)) cnt++;
}
} else
{
if (c[i].b>=&&i!=(l-))
{
int k1=c[i].a,k2=pos2(i+);
if (pos(k1+)<pos(k2+)) cnt++;
}
if (c[i].b>=)
{
int k1=c[i].a+c[i].b-,k2=c[i].a+c[i].b-;
if (pos(k1+)<pos(k2+)) cnt++;
}
}
}
cout<<fsp(,cnt)<<endl;
return ;
}

Very Long Suffix Array的更多相关文章

  1. 后缀数组(suffix array)详解

    写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...

  2. 后缀数组(suffix array)

    参考: Suffix array - Wiki 后缀数组(suffix array)详解 6.3   Suffix Arrays - 算法红宝书 Suffix Array 后缀数组 基本概念 应用:字 ...

  3. Suffix array

    A suffix array is a sorted array of all suffixes of a given string. The definition is similar to Suf ...

  4. 利用后缀数组(suffix array)求最长公共子串(longest common substring)

    摘要:本文讨论了最长公共子串的的相关算法的时间复杂度,然后在后缀数组的基础上提出了一个时间复杂度为o(n^2*logn),空间复杂度为o(n)的算法.该算法虽然不及动态规划和后缀树算法的复杂度低,但其 ...

  5. 笔试算法题(40):后缀数组 & 后缀树(Suffix Array & Suffix Tree)

    议题:后缀数组(Suffix Array) 分析: 后缀树和后缀数组都是处理字符串的有效工具,前者较为常见,但后者更容易编程实现,空间耗用更少:后缀数组可用于解决最长公共子串问题,多模式匹配问题,最长 ...

  6. 数据结构之后缀数组suffix array

    在字符串处理当中,后缀树和后缀数组都是非常有力的工具,其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料.其实后缀是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多 ...

  7. suffix array后缀数组

    倍增算法 基本定义子串:字符串 S 的子串 r[i..j],i≤j,表示 r 串中从 i 到 j 这一段也就是顺次排列 r[i],r[i+1],...,r[j]形成的字符串. 后缀:后缀是指从某个位置 ...

  8. 后缀数组suffix array

    倍增算法,时间复杂度O(nlogn) sa从小到大保存相对大小的下标 理解LSD,x数组,sa数组 char s[maxn]; int sa[maxn],t[maxn],t2[maxn],c[maxn ...

  9. 后缀数组 (Suffix Array) 学习笔记

    \(\\\) 定义 介绍一些写法和数组的含义,首先要知道 字典序 . \(len\):字符串长度 \(s\):字符串数组,我们的字符串存储在 \(s[0]...s[len-1]\) 中. \(suff ...

随机推荐

  1. P4178 Tree(点分治)

    题面要求小于等于K的路径数目,我么很自然的想到点分治(不会的就戳我) 这道题的统计答案与模板题不一样的地方是由等于K到小于等于K 那么我们可以把每一个子节点到当前根(重心)的距离排序,然后用类似双指针 ...

  2. 3754. 【NOI2014】魔法森林(LCT)

    Problem 给定一个\(n\)个结点,\(m\)条边的的无向图,每条边有两个权值\(ai,bi\). 现在从\(1\)出发,要到达\(n\),每次只能沿着\(ai\le A\)且\(bi\le B ...

  3. JAVA helloworld!

    idea创建java项目 https://jingyan.baidu.com/article/48b558e3f8f6637f39c09a44.html 本地文档运行 java helloworld ...

  4. Linux系统下DHCP服务安装部署和使用详解

    一.概述 DHCP :动态主机设置协议(英语:Dynamic Host Configuration Protocol,DHCP)是一个局域网的网络协议,使用UDP协议工作,主要有两个用途:用于内部网或 ...

  5. 如何安装 PhoneGap / Cordova (for Win10)

    最近需要配置 PhoneGap / Cordova 环境,折腾了一阵子,写篇博客 Mark 一下整个过程. 具体参照了:http://www.assortedgarbage.com/apigee/ 以 ...

  6. JGUI源码:开发中遇到的问题(11)

    1.IE8下浏览器下css body边缘要留一个像素,如果不留的话,很有可能看不到最边缘的像素. 2.同一种颜色在深色背景和浅色背景下给人的感觉不一样,在深色背景下,给人感觉特别亮,所以深色背景下的颜 ...

  7. ioctl函数

    一.函数原型 #include <unistd.h> int ioctl(int fd, int request, .../* void *arg */); 二.和网络相关的请求(requ ...

  8. SimpleDateFormat 线程不安全及解决方案

    SimpleDateFormat定义 SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类.它允许进行格式化(日期 -> 文本).解析(文本 -> 日期 ...

  9. 移除文件(git rm)

    git rm`命令会把文件从已跟踪列表(及暂存区)中移除,并且移除把文件从工作目录中移除,这样下一次你就不会在未跟踪文件列表中看到这些文件了. 如果你只是简单的把文件从工作目录移除,而没有使用git ...

  10. Selenium中三种等待的使用方式---规避网络延迟、代码不稳定问题

    在UI自动化测试中,必然会遇到环境不稳定,网络慢的情况,这时如果你不做任何处理的话,代码会由于没有找到元素,而报错.这时我们就要用到wait(等待),而在Selenium中,我们可以用到一共三种等待, ...