dfs序 线段树 dfs序列 主席树

并查集

#include<stdio.h>
int stt[10005];
void sset(int x)
{
    for(int i=1;i<=x;i++) stt[i]=i;
}
int ffind(int x)
{
    if(x==stt[x]) return x;
    else return stt[x]=ffind(stt[x]);
}
void Union(int a,int b)
{
    int x=ffind(a);
    int y=ffind(b);
    if(x==y) return;
    stt[y]=x;
}
int main()
{
    sset(10000);
    /*  */
}
View Code

树状数组  (一般单点修改  区间查询)

#include<bits/stdc++.h>
#define int long long
#define MAX(a,b,c) max(a,max(b,c))
#define MIN(a,b,c) min(a,min(b,c))
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef unsigned long long uLL;
using namespace std;
const int maxn=5e5+10;
const int INF=0x3f3f3f3f;
int a[maxn];
int n;
int lowbit(int x){return x&(-x); }
void update(int b,int c)
{
     while(b<=n)
     {
         a[b]+=c; b=b+lowbit(b);
     }
}
int getsum(int x)
{
    int sum=0;
    while(x)
    {
        sum+=a[x];
        x-=lowbit(x);
    }
    return sum;
}
int32_t main()
{
   int q; cin>>n>>q;
   for(int i=1;i<=n;i++)
   {
       int x; cin>>x;
       update(i,x);
   }
   while(q--)
   {
       int x,b,c;
       cin>>x>>b>>c;
       if(x==1) {update(b,c);}
       if(x==2)
       {
           cout<<getsum(c)-getsum(b-1)<<endl;
       }
   }
}

区间求值
View Code

一个其他学法的数组数组

#include<bits/stdc++.h>
//#define int long long
#define MAX(a,b,c) max(a,max(b,c))
#define MIN(a,b,c) min(a,min(b,c))
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef long long LL;
typedef unsigned long long ull;
typedef unsigned long long uLL;
using namespace std;
const int maxn=5e5+10;
int a[maxn];
int n;
int lowbit(int x){return x&(-x); }
void update(int x,int c)
{
    while(x)
    {
        a[x]+=c;
        x=x-lowbit(x);
    }
}
int getsum(int x)
{
    int sum=0;;
    while(x<=n)
    {
        sum+=a[x]; x+=lowbit(x);
    }return sum;
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int q; cin>>n>>q;
    for(int i=1;i<=n;i++)
    {
        int x; cin>>x;  update(i,x); update(i-1,-x);
    }
    while(q--)
    {
        int x;cin>>x;
        if(x==1) { int a,b,c; cin>>a>>b>>c; update(b,c); update(a-1,-c);}
        if(x==2) { int a;     cin>>a; cout<<getsum(a)<<endl;}
    }

}

求点的值
View Code

线段树 模板

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int maxn=1e5+10;
struct NODE
{
    int l,r,w,f; // f 为lazy标记
}tree[4*maxn+10];
void build(int p,int q,int k)
{
    tree[k].l=p;  tree[k].r=q;
    if(tree[k].l==tree[k].r)  { cin>>tree[k].w;/* cout<<"==="<<tree[k].w<<endl;*/ return ; }
    int mid=( tree[k].l+tree[k].r )/2;
    build(p,mid,2*k);
    build(mid+1,q,2*k+1);
    tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
void down(int k)  // (lazy  标记) (××××) (important)
{
    tree[2*k].f+=tree[k].f;
    tree[2*k+1].f+=tree[k].f;
    tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
    tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
    tree[k].f=0;
}
void change_interval(int a,int b,int x,int k) // 区间修改  区间加值;
{
    if(tree[k].l>=a && tree[k].r<=b )
    {
        tree[k].w+=(tree[k].r-tree[k].l+1)*x;
        tree[k].f+=x;
        return;
    }
    if(tree[k].f) down(k);
    int mid=(tree[k].l+tree[k].r)/2;
    if(b<=mid)         change_interval(a,b,x,2*k);
    else if(a>=mid+1)  change_interval(a,b,x,2*k+1);
    else               change_interval(a,mid,x,2*k),change_interval(mid+1,b,x,2*k+1);
    tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
void change_point(int x,int k)
{
    if(tree[k].l==tree[k].r) { tree[k].w+=x; return; }
    if(tree[k].f) down(k);
    int mid=(tree[k].l+tree[k].r)/2;
    if(x<=mid) change_point(x,2*k);
    else       change_point(x,2*k+1);
    tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
int ask_interval(int a,int b,int k)  // 区间查询
{
    int num=0;
    if(tree[k].l>=a&&tree[k].r<=b)
    {
        num+=tree[k].w;
        return num;
    }
    if(tree[k].f) down(k);
    int mid=( tree[k].l+tree[k].r)/2;
    if(b<=mid)        num+=ask_interval(a,b,2*k);
    else if(a>=mid+1) num+=ask_interval(a,b,2*k+1);
    else              num+=ask_interval(a,mid,2*k)+ask_interval(mid+1,b,2*k+1);
    return num;
}
int ask_point(int x,int k)  // 点查询
{
     int num=0;
     if(tree[k].l==tree[k].r) {return tree[k].w; }
     if(tree[k].f) down(k);
     int mid=(tree[k].l+tree[k].r)/2;
     if(x<=mid) ask_point(x,2*k);
     if(x>=mid+1) ask_point(x,2*k+1);
}
int32_t main()
{
}
View Code

主席树 模板  hdu 2665

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
const int M=100005*20;
int root[N],lson[M],rson[M],v[M];
int a[N],b[N];
int tot=0;
vector<int> vs;
map<int,int> mp;
void build(int &x,int l,int r){
    x=++tot;  //cout<<x<<endl;
    if(l==r) { v[x]=0; return; }
    int mid=(l+r)/2;
    build(lson[x],l,mid);
    build(rson[x],mid+1,r);
    v[x]=v[lson[x]]+v[rson[x]];
}
void update(int odd,int &x,int pos,int value,int l,int r){
    x=++tot;  v[x]=v[odd]+value; lson[x]=lson[odd]; rson[x]=rson[odd]; // 构链
    if(l==r)  {  return ; }
    int mid=(l+r)/2;
    if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
    else         update(rson[odd],rson[x],pos,value,mid+1,r);
    //v[x]=v[lson[x]]+v[rson[x]];
}
int query(int odd,int x,int k,int l,int r){
    int num=v[lson[x]]-v[lson[odd]];
    if(l==r)   return l;
    if(k<=num) return query(lson[odd],lson[x],k,l,(l+r)/2);
    else       return query(rson[odd],rson[x],k-num,(l+r)/2+1,r);
}
int main(){
    int T; scanf("%d",&T);
    while(T--){
        int n,m; scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) vs.push_back(a[i]);
        sort(vs.begin(),vs.end());
        vs.erase(unique(vs.begin(),vs.end()),vs.end());
        for(int i=0;i<vs.size();i++)  mp[vs[i]]=i+1,b[i+1]=vs[i];
        //for(int i=0;i<vs.size();i++) cout<<vs[i]<<" "<<mp[vs[i]]<<endl; cout<<endl;
        int nn=vs.size();
        build(root[0],1,nn);
        for(int i=1;i<=n;i++){
            int pos=mp[a[i]];  //cout<<mp[a[i]]<<endl;
            update(root[i-1],root[i],pos,1,1,nn);
        }
        for(int i=1;i<=m;i++){
            int l,r,k; scanf("%d %d %d",&l,&r,&k);
            int ans=query(root[l-1],root[r],k,1,nn);
            printf("%d
",b[ans]);
        }
        vs.clear();
        mp.clear();
        for(int i=0;i<=n;i++) root[i]=0;
        tot=0;
    }
}
View Code

dfs 线段树   poj3321

#include<cstdio>
#include<vector>
using namespace std;
const int maxn=1e5+10;
pair<int,int> pa[maxn];
int head[maxn],cnt=0;
struct EDGE { int next,to; } edge[maxn];
void ADD(int u,int v){
    edge[++cnt].next=head[u];
    edge[cnt].to=v;
    head[u]=cnt;
}
int tot=0;
void dfs(int x,int fa){
    pa[x].first=++tot;
    for(int i=head[x];i!=0;i=edge[i].next){
        int u=edge[i].to;
        if(u==fa) continue;
        dfs(u,x);
    }
    pa[x].second=tot;
}
struct NODE { int l,r,w; }tree[4*maxn+10];
void build(int p,int q,int k){
    tree[k].l=p;  tree[k].r=q;
    if(tree[k].l==tree[k].r)  { tree[k].w=1; return ; }
    int mid=( tree[k].l+tree[k].r )/2;
    build(p,mid,2*k);  build(mid+1,q,2*k+1);
    tree[k].w=tree[2*k].w+tree[2*k+1].w;
}
void change_interval(int a,int b,int x,int k) // 区间修改  区间加值;
{
    if(tree[k].l>=a && tree[k].r<=b ){
        if(tree[k].w==1) tree[k].w=0;
        else             tree[k].w=1;
        return;
    }
    int mid=(tree[k].l+tree[k].r)/2;
    if(b<=mid)         change_interval(a,b,x,2*k);
    else if(a>=mid+1)  change_interval(a,b,x,2*k+1);
    else               change_interval(a,mid,x,2*k),change_interval(mid+1,b,x,2*k+1);
    tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
int ask_interval(int a,int b,int k)  // 区间查询
{
    int num=0;
    if(tree[k].l>=a&&tree[k].r<=b){
        num=tree[k].w;
        return num;
    }
    int mid=( tree[k].l+tree[k].r)/2;
    if(b<=mid)        num+=ask_interval(a,b,2*k);
    else if(a>=mid+1) num+=ask_interval(a,b,2*k+1);
    else              num+=ask_interval(a,mid,2*k)+ask_interval(mid+1,b,2*k+1);
    return num;
}
char ch[2];
int c;
int main(){
    int n; scanf("%d",&n);
    for(int i=1;i<=n-1;i++){
        int  x,y; scanf("%d %d",&x,&y);ADD(x,y);
    }
    dfs(1,1);
    build(1,n,1);
    int q; scanf("%d",&q);
    while(q--){
        scanf("%s %d",ch,&c);
        if(ch[0]=='Q') {
            printf("%d
",ask_interval(pa[c].first,pa[c].second,1));
        }
        else {
           change_interval(pa[c].first,pa[c].first,1,1);
        }

    }
}
View Code

  dfs序列  主席树  hdu 5678

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=4e5+10;
const int mod=1e9+7;
const int inv2=(1+mod)/2;
int a[maxn],b[maxn];
pair<int,int> pa[maxn];
int head[maxn],cnt=0;
struct EDGE { int next,to; } edge[maxn];
void ADD(int u,int v){
    edge[++cnt].next=head[u];
    edge[cnt].to=v;
    head[u]=cnt;
}
int tot=0;
void dfs(int x,int fa){
    pa[x].first=++tot; a[tot]=b[x];
    for(int i=head[x];i!=0;i=edge[i].next){
        int u=edge[i].to;
        if(u==fa) continue;
        dfs(u,x);
    } pa[x].second=tot;
}

int c[maxn*10];
int qqq[maxn*10];
int root[maxn],lson[maxn*20],rson[maxn*20],v[maxn*20];
void build(int &x,int l,int r){
    x=++tot;  //cout<<x<<endl;
    if(l==r) { v[x]=0; return; }
    int mid=(l+r)/2;
    build(lson[x],l,mid);
    build(rson[x],mid+1,r);
    v[x]=v[lson[x]]+v[rson[x]];
}
void update(int odd,int &x,int pos,int value,int l,int r){
    x=++tot;  v[x]=v[odd]+value; lson[x]=lson[odd]; rson[x]=rson[odd]; // 构链
    if(l==r)  {  return ; }
    int mid=(l+r)/2;
    if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
    else         update(rson[odd],rson[x],pos,value,mid+1,r);
}
int query(int odd,int x,int k,int l,int r){
    int num=v[lson[x]]-v[lson[odd]];
    if(l==r)   return l;
    if(k<=num) return query(lson[odd],lson[x],k,l,(l+r)/2);
    else       return query(rson[odd],rson[x],k-num,(l+r)/2+1,r);
}

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
map<int,int> mp;
vector<int> vs;
int kkk[maxn];
int main(){
    c[0]=1; for(int i=1;i<maxn*10;i++){ c[i]=1ll*c[i-1]*10%mod; }
    int T; T=read();
    while(T--){
        vs.clear();
        mp.clear();
         cnt=0; tot=0;
        int n,q; n=read(); q=read();
        for(int i=1;i<=n;i++) b[i]=read();
        for(int i=1;i<=n;i++) vs.push_back(b[i]);
        sort(vs.begin(),vs.end());
        vs.erase(unique(vs.begin(),vs.end()),vs.end());
        for(int i=0;i<vs.size();i++) { mp[vs[i]]=i+1; kkk[i+1]=vs[i]; }
        for(int i=1;i<=n;i++)          b[i]=mp[b[i]];
        for(int i=1;i<=n-1;i++)      { int  x,y; x=read(); y=read(); ADD(x,y); }
        dfs(1,1);
        build(root[0],1,n);
        for(int i=1;i<=n;i++){  update(root[i-1],root[i],a[i],1,1,n); }
        ll ans=0;
        double f=0;
        for(int i=1;i<=q;i++){
            int k; k=read();
            int r=pa[k].second;
            int l=pa[k].first;
            int d=(r-l+1);
            if(d%2==1){
                int w=(d+1)/2;
                int temp;
                if(qqq[k]==0 )  { temp=kkk[query(root[l-1],root[r],w,1,n)]; qqq[k]=temp; }
                temp=qqq[k];
                ans+=1ll*temp*c[q-i]%mod;
            }
            else {
                int w=d/2;
                int temp=0;
                if(qqq[k]==0){
                   temp+=kkk[query(root[l-1],root[r],w,1,n)]+kkk[query(root[l-1],root[r],w+1,1,n)];
                   qqq[k]=temp;
                }
                temp=qqq[k];
                if(i==q){
                    if(temp%2==1)   f=0.5,ans+=temp/2;
                    else            ans+=1ll*temp/2%mod;
                }
                else {
                     ans+=1ll*temp*5%mod*c[q-i-1]%mod;
                }
            }
        }
        f+=ans%mod;
        printf("%.1f
",f);
        for(int i=1;i<=n;i++){
          qqq[i]=0; head[i]=0;  edge[i].next=0; edge[i].to=0;
        }
    }
    return 0;
}
View Code

 dfs序列  主席树 后缀自动机(主要用到后缀树 ) 树上倍增    /   后缀数组  主席树   st表 二分

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int inv2=(1+mod)/2;
int n,m;
struct SAM
{
    static const int MAXN = 200030<<1;//大小为字符串长度两倍
    static const int maxn = 200030<<1;
    static const int LetterSize = 30;
    int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
    int num[maxn];    // 自动机->字符串结束位置
    int renum[maxn];  // 结束位置-> 自动机位置
    int num_0[maxn];
    void init( void){
        last = tot = 1;  len[1] = 0;
        memset( ch[1], 0, sizeof ch[1]);
    }
    void add( int x,int c) {
        int p = last, np = last = ++tot;  num[tot]=c+1; renum[c+1]=tot; // 记录结束位置
        len[np] = len[p] + 1;
        memset( ch[np], 0, sizeof ch[np]);
        while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
        if( p == 0)  fa[np] = 1;
        else{
            int q = ch[p][x];
            if( len[q] == len[p] + 1)  fa[np] = q;
            else
            {
                int nq = ++tot;
                memcpy( ch[nq], ch[q], sizeof ch[q]);
                len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
                while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
            }
        }
    }
    int root[maxn],lson[maxn*80],rson[maxn*80],v[maxn*80];
    int w=0;
    void build(int &x,int l,int r){
        x=++w;  //cout<<x<<endl;
        if(l==r) { v[x]=0; return; }
        int mid=(l+r)/2;
        build(lson[x],l,mid);
        build(rson[x],mid+1,r);
        v[x]=v[lson[x]]+v[rson[x]];
    }
    void update(int odd,int &x,int pos,int value,int l,int r){
        x=++w;  v[x]=v[odd]+value; lson[x]=lson[odd]; rson[x]=rson[odd]; // ¹¹Á´
        if(l==r)  {  return ; }
        int mid=(l+r)/2;
        if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
        else         update(rson[odd],rson[x],pos,value,mid+1,r);
    }
    int query(int odd,int x,int k,int l,int r){
        int num=v[lson[x]]-v[lson[odd]];
        if(l==r)   return l;
        if(k<=num) return query(lson[odd],lson[x],k,l,(l+r)/2);
        else       return query(rson[odd],rson[x],k-num,(l+r)/2+1,r);
    }
    vector<int> vs[maxn];
    int bz[maxn][20];
    int a[maxn];  //主席树上系列 -> 结束位置
    pair<int,int> pa[maxn];  // dfs 序列
    int k=0;
    void dfs(int x,int fa){
        bz[x][0]=fa;  pa[x].first=++k;   a[k]=num[x]; //
        for(int i=1;i<=19;i++)   bz[x][i]=bz[bz[x][i-1]][i-1];  // 树上倍增
        for(int i=0;i<vs[x].size();i++){  dfs(vs[x][i],x);num_0[x]+=num_0[vs[x][i]]; }
        pa[x].second=k;
        if(num[x]==0) num_0[x]++;

    }
    void make_tu(){
        for(int i=2;i<=tot;i++)  vs[fa[i]].push_back(i);dfs(1,0);
    }
    void make(){
        make_tu();
        build(root[0],1,tot);
        for(int i=1;i<=tot;i++){  update(root[i-1],root[i],a[i]+1,1,1,tot+1); }
    }
    void slove(){
        for(int i=1;i<=m;i++){
            int l,r,k; scanf("%d %d %d",&l,&r,&k);
            int d=r-l+1;
            int pos=renum[r];
            for(int i=19;i>=0;i--){
                if(len[bz[pos][i]]>=d) pos=bz[pos][i];
            }
            int lll=pa[pos].first;
            int rrr=pa[pos].second;
            int ddd=rrr-lll+1;
            if(k+num_0[pos]>ddd){
                printf("-1
");
            }
            else {
                int w=query(root[lll-1],root[rrr],k+num_0[pos],1,tot+1);
                if(w==1) printf("-1
");
                else     printf("%d
",w-d);
            }
        }
        for(int i=0;i<=tot+10;i++){
            vs[i].clear(); num_0[i]=0; num[i]=0; renum[i]=0;
        }
        k=0;
    }
}sam;
char ss[100005];
int main(){
    int T; scanf("%d",&T);
    while(T--){
        sam.init();
        scanf("%d %d",&n,&m); scanf("%s",ss);
        for(int i=0;i<n;i++) sam.add(ss[i]-'a',i);
        sam.make();
        sam.slove();
    }
    return 0;
}
View Code
#include<bits/stdc++.h>
#define rank rk
using namespace std;
const int maxn = 1050005;
const int N=1050005;
const int M=N*20;
int sa[maxn], rank[maxn], height[maxn];
int wa[maxn], wb[maxn], wv[maxn], cnt[maxn];
void SA(int *r, int n, int m) {
    int *x = wa, *y = wb;
    for(int i = 0; i < m; i++) cnt[i] = 0;
    for(int i = 0; i < n; i++) cnt[x[i] = r[i]]++;
    for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];
    for(int i = n - 1; i >= 0; i--) sa[--cnt[x[i]]] = i;
    for(int j = 1; j < n; j <<= 1) {
        int p = 0;
        for(int i = n - j; i < n; i++) y[p++] = i;
        for(int i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j;
        for(int i = 0; i < n; i++) wv[i] = x[y[i]];
        for(int i = 0; i < m; i++) cnt[i] = 0;
        for(int i = 0; i < n; i++) cnt[wv[i]]++;
        for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];
        for(int i = n - 1; i >= 0; i--) sa[--cnt[wv[i]]] = y[i];
        swap(x, y);
        p = 1; x[sa[0]] = 0;
        for(int i = 1; i < n; i++)
            x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + j] == y[sa[i] + j] ? p - 1 : p++;
        if(p >= n) break;
        m = p;
    }
}
void calcHeight(int *r, int n) {
    int i, j, k;
    for(i = j = k = 0; i < n; height[rank[i++]] = k)
        for(k ? k-- : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; k++);
}
int n, s[maxn];
int a[maxn];
char str[maxn];
int root[N],lson[M],rson[M],v[M];
int tot=0;
void build(int &x,int l,int r){
    x=++tot;  //cout<<x<<endl;
    if(l==r) { v[x]=0; return; }
    int mid=(l+r)/2;
    build(lson[x],l,mid);
    build(rson[x],mid+1,r);
    v[x]=v[lson[x]]+v[rson[x]];
}
void update(int odd,int &x,int pos,int value,int l,int r){
    x=++tot;  v[x]=v[odd]+value; lson[x]=lson[odd]; rson[x]=rson[odd]; // 构链
    if(l==r)  {  return ; }
    int mid=(l+r)/2;
    if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
    else         update(rson[odd],rson[x],pos,value,mid+1,r);
}
int query(int odd,int x,int k,int l,int r){
    int num=v[lson[x]]-v[lson[odd]];
    if(l==r)   return l;
    if(k<=num) return query(lson[odd],lson[x],k,l,(l+r)/2);
    else       return query(rson[odd],rson[x],k-num,(l+r)/2+1,r);
}
int lg[maxn];
int st[maxn][20];
void make_ST(){
     for(int i=n;i>=1;i--){
         st[i][0]=height[i];
         for(int j=1;i+(1<<j-1)-1<=n;j++){
             st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
         }
        // cout<<st[i][0]<<endl;
     }
}
bool st_check(int l,int r,int d){
    if(l==r) return 1;
    l++;
    int k=lg[r-l+1];
    int m=min(st[l][k],st[r-(1<<k)+1][k]);
    if(m>=d) return 1;
    else     return 0;
}
int check1(int l,int r,int d){
    int x=l;
    int mid=(l+r)/2;
    while(l<r){
        if(st_check(x,mid,d)) l=mid;
        else                  r=mid-1;
        mid=(l+r+1)/2;
    }
    return mid;
}
int check2(int l,int r,int d){
    int x=r;
    int mid=(l+r)/2;
    while(l<r){
       // cout<<l<<" "<<r<<"  "<<mid<<"  "<<st_check(mid,x,d)<<endl;;
        if(st_check(mid,x,d)) r=mid;
        else                  l=mid+1;
        mid=(l+r)/2;
    }
    return mid;
}
void make(int l,int r,int k){

    int d=(r-l+1);
    int pos=rank[l-1];
    int rr,ll;
    rr=check1(pos,n,d);
    ll=check2(1,pos,d);
    int w=rr-ll+1;
    if(w<k) printf("-1
");
    else    {
         int ans=query(root[ll-1],root[rr],k,1,n);
         printf("%d
",ans);
    }
}
int main() {
    for(int i=2;i<maxn;i++){lg[i]=lg[i>>1]+1;}
    int T; scanf("%d", &T);
    while(T--) {
        int q; scanf("%d %d",&n,&q);
        scanf("%s", str);  n = strlen(str);
        for(int i = 0; i < n; i++) s[i] = str[i]; s[n] = 0;
        SA(s, n + 1, 300);
        for(int i = 0; i <= n; i++) rank[sa[i]] = i;
        calcHeight(s, n);
        make_ST();
        int nn=n;
        build(root[0],1,nn);
        for(int i=1;i<=n;i++) a[i]=sa[i]+1;
       // for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
        for(int i=1;i<=n;i++) update(root[i-1],root[i],a[i],1,1,nn);
        while(q--){
            int l,r,k; scanf("%d %d %d",&l,&r,&k);
            make(l,r,k);
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Andromeda-Galaxy/p/11469279.html