zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    南大《软件分析》课程笔记——Intermediate Representation
    leetcode刷题
    shiro550反序列化分析
    南大《软件分析》课程笔记——第一课
    再见2020
    S2-002漏洞分析
    编码&解码工具
    正码、反码和补码
    Java数据结构(二)
    Java数据集合
  • 原文地址:https://www.cnblogs.com/Andromeda-Galaxy/p/11469279.html
Copyright © 2011-2022 走看看