并查集

  1. #include<stdio.h>
  2. int stt[];
  3. void sset(int x)
  4. {
  5. for(int i=;i<=x;i++) stt[i]=i;
  6. }
  7. int ffind(int x)
  8. {
  9. if(x==stt[x]) return x;
  10. else return stt[x]=ffind(stt[x]);
  11. }
  12. void Union(int a,int b)
  13. {
  14. int x=ffind(a);
  15. int y=ffind(b);
  16. if(x==y) return;
  17. stt[y]=x;
  18. }
  19. int main()
  20. {
  21. sset();
  22. /* */
  23. }

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

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define MAX(a,b,c) max(a,max(b,c))
  4. #define MIN(a,b,c) min(a,min(b,c))
  5. #define pb push_back
  6. #define fi first
  7. #define se second
  8. typedef long long ll;
  9. typedef long long LL;
  10. typedef unsigned long long ull;
  11. typedef unsigned long long uLL;
  12. using namespace std;
  13. const int maxn=5e5+;
  14. const int INF=0x3f3f3f3f;
  15. int a[maxn];
  16. int n;
  17. int lowbit(int x){return x&(-x); }
  18. void update(int b,int c)
  19. {
  20. while(b<=n)
  21. {
  22. a[b]+=c; b=b+lowbit(b);
  23. }
  24. }
  25. int getsum(int x)
  26. {
  27. int sum=;
  28. while(x)
  29. {
  30. sum+=a[x];
  31. x-=lowbit(x);
  32. }
  33. return sum;
  34. }
  35. int32_t main()
  36. {
  37. int q; cin>>n>>q;
  38. for(int i=;i<=n;i++)
  39. {
  40. int x; cin>>x;
  41. update(i,x);
  42. }
  43. while(q--)
  44. {
  45. int x,b,c;
  46. cin>>x>>b>>c;
  47. if(x==) {update(b,c);}
  48. if(x==)
  49. {
  50. cout<<getsum(c)-getsum(b-)<<endl;
  51. }
  52. }
  53. }
  54.  
  55. 区间求值

一个其他学法的数组数组

  1. #include<bits/stdc++.h>
  2. //#define int long long
  3. #define MAX(a,b,c) max(a,max(b,c))
  4. #define MIN(a,b,c) min(a,min(b,c))
  5. #define pb push_back
  6. #define fi first
  7. #define se second
  8. typedef long long ll;
  9. typedef long long LL;
  10. typedef unsigned long long ull;
  11. typedef unsigned long long uLL;
  12. using namespace std;
  13. const int maxn=5e5+;
  14. int a[maxn];
  15. int n;
  16. int lowbit(int x){return x&(-x); }
  17. void update(int x,int c)
  18. {
  19. while(x)
  20. {
  21. a[x]+=c;
  22. x=x-lowbit(x);
  23. }
  24. }
  25. int getsum(int x)
  26. {
  27. int sum=;;
  28. while(x<=n)
  29. {
  30. sum+=a[x]; x+=lowbit(x);
  31. }return sum;
  32. }
  33. int main()
  34. {
  35. ios::sync_with_stdio(false); cin.tie(); cout.tie();
  36. int q; cin>>n>>q;
  37. for(int i=;i<=n;i++)
  38. {
  39. int x; cin>>x; update(i,x); update(i-,-x);
  40. }
  41. while(q--)
  42. {
  43. int x;cin>>x;
  44. if(x==) { int a,b,c; cin>>a>>b>>c; update(b,c); update(a-,-c);}
  45. if(x==) { int a; cin>>a; cout<<getsum(a)<<endl;}
  46. }
  47.  
  48. }
  49.  
  50. 求点的值

线段树 模板

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. using namespace std;
  4. const int maxn=1e5+;
  5. struct NODE
  6. {
  7. int l,r,w,f; // f 为lazy标记
  8. }tree[*maxn+];
  9. void build(int p,int q,int k)
  10. {
  11. tree[k].l=p; tree[k].r=q;
  12. if(tree[k].l==tree[k].r) { cin>>tree[k].w;/* cout<<"==="<<tree[k].w<<endl;*/ return ; }
  13. int mid=( tree[k].l+tree[k].r )/;
  14. build(p,mid,*k);
  15. build(mid+,q,*k+);
  16. tree[k].w=tree[*k].w+tree[*k+].w;
  17. }
  18. void down(int k) // (lazy 标记) (××××) (important)
  19. {
  20. tree[*k].f+=tree[k].f;
  21. tree[*k+].f+=tree[k].f;
  22. tree[k*].w+=tree[k].f*(tree[k*].r-tree[k*].l+);
  23. tree[k*+].w+=tree[k].f*(tree[k*+].r-tree[k*+].l+);
  24. tree[k].f=;
  25. }
  26. void change_interval(int a,int b,int x,int k) // 区间修改 区间加值;
  27. {
  28. if(tree[k].l>=a && tree[k].r<=b )
  29. {
  30. tree[k].w+=(tree[k].r-tree[k].l+)*x;
  31. tree[k].f+=x;
  32. return;
  33. }
  34. if(tree[k].f) down(k);
  35. int mid=(tree[k].l+tree[k].r)/;
  36. if(b<=mid) change_interval(a,b,x,*k);
  37. else if(a>=mid+) change_interval(a,b,x,*k+);
  38. else change_interval(a,mid,x,*k),change_interval(mid+,b,x,*k+);
  39. tree[k].w=tree[k*].w+tree[k*+].w;
  40. }
  41. void change_point(int x,int k)
  42. {
  43. if(tree[k].l==tree[k].r) { tree[k].w+=x; return; }
  44. if(tree[k].f) down(k);
  45. int mid=(tree[k].l+tree[k].r)/;
  46. if(x<=mid) change_point(x,*k);
  47. else change_point(x,*k+);
  48. tree[k].w=tree[k*].w+tree[k*+].w;
  49. }
  50. int ask_interval(int a,int b,int k) // 区间查询
  51. {
  52. int num=;
  53. if(tree[k].l>=a&&tree[k].r<=b)
  54. {
  55. num+=tree[k].w;
  56. return num;
  57. }
  58. if(tree[k].f) down(k);
  59. int mid=( tree[k].l+tree[k].r)/;
  60. if(b<=mid) num+=ask_interval(a,b,*k);
  61. else if(a>=mid+) num+=ask_interval(a,b,*k+);
  62. else num+=ask_interval(a,mid,*k)+ask_interval(mid+,b,*k+);
  63. return num;
  64. }
  65. int ask_point(int x,int k) // 点查询
  66. {
  67. int num=;
  68. if(tree[k].l==tree[k].r) {return tree[k].w; }
  69. if(tree[k].f) down(k);
  70. int mid=(tree[k].l+tree[k].r)/;
  71. if(x<=mid) ask_point(x,*k);
  72. if(x>=mid+) ask_point(x,*k+);
  73. }
  74. int32_t main()
  75. {
  76. }

主席树 模板  hdu 2665

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=;
  4. const int M=*;
  5. int root[N],lson[M],rson[M],v[M];
  6. int a[N],b[N];
  7. int tot=;
  8. vector<int> vs;
  9. map<int,int> mp;
  10. void build(int &x,int l,int r){
  11. x=++tot; //cout<<x<<endl;
  12. if(l==r) { v[x]=; return; }
  13. int mid=(l+r)/;
  14. build(lson[x],l,mid);
  15. build(rson[x],mid+,r);
  16. v[x]=v[lson[x]]+v[rson[x]];
  17. }
  18. void update(int odd,int &x,int pos,int value,int l,int r){
  19. x=++tot; v[x]=v[odd]+value; lson[x]=lson[odd]; rson[x]=rson[odd]; // 构链
  20. if(l==r) { return ; }
  21. int mid=(l+r)/;
  22. if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
  23. else update(rson[odd],rson[x],pos,value,mid+,r);
  24. //v[x]=v[lson[x]]+v[rson[x]];
  25. }
  26. int query(int odd,int x,int k,int l,int r){
  27. int num=v[lson[x]]-v[lson[odd]];
  28. if(l==r) return l;
  29. if(k<=num) return query(lson[odd],lson[x],k,l,(l+r)/);
  30. else return query(rson[odd],rson[x],k-num,(l+r)/+,r);
  31. }
  32. int main(){
  33. int T; scanf("%d",&T);
  34. while(T--){
  35. int n,m; scanf("%d %d",&n,&m);
  36. for(int i=;i<=n;i++) scanf("%d",&a[i]);
  37. for(int i=;i<=n;i++) vs.push_back(a[i]);
  38. sort(vs.begin(),vs.end());
  39. vs.erase(unique(vs.begin(),vs.end()),vs.end());
  40. for(int i=;i<vs.size();i++) mp[vs[i]]=i+,b[i+]=vs[i];
  41. //for(int i=0;i<vs.size();i++) cout<<vs[i]<<" "<<mp[vs[i]]<<endl; cout<<endl;
  42. int nn=vs.size();
  43. build(root[],,nn);
  44. for(int i=;i<=n;i++){
  45. int pos=mp[a[i]]; //cout<<mp[a[i]]<<endl;
  46. update(root[i-],root[i],pos,,,nn);
  47. }
  48. for(int i=;i<=m;i++){
  49. int l,r,k; scanf("%d %d %d",&l,&r,&k);
  50. int ans=query(root[l-],root[r],k,,nn);
  51. printf("%d\n",b[ans]);
  52. }
  53. vs.clear();
  54. mp.clear();
  55. for(int i=;i<=n;i++) root[i]=;
  56. tot=;
  57. }
  58. }

dfs 线段树   poj3321

  1. #include<cstdio>
  2. #include<vector>
  3. using namespace std;
  4. const int maxn=1e5+;
  5. pair<int,int> pa[maxn];
  6. int head[maxn],cnt=;
  7. struct EDGE { int next,to; } edge[maxn];
  8. void ADD(int u,int v){
  9. edge[++cnt].next=head[u];
  10. edge[cnt].to=v;
  11. head[u]=cnt;
  12. }
  13. int tot=;
  14. void dfs(int x,int fa){
  15. pa[x].first=++tot;
  16. for(int i=head[x];i!=;i=edge[i].next){
  17. int u=edge[i].to;
  18. if(u==fa) continue;
  19. dfs(u,x);
  20. }
  21. pa[x].second=tot;
  22. }
  23. struct NODE { int l,r,w; }tree[*maxn+];
  24. void build(int p,int q,int k){
  25. tree[k].l=p; tree[k].r=q;
  26. if(tree[k].l==tree[k].r) { tree[k].w=; return ; }
  27. int mid=( tree[k].l+tree[k].r )/;
  28. build(p,mid,*k); build(mid+,q,*k+);
  29. tree[k].w=tree[*k].w+tree[*k+].w;
  30. }
  31. void change_interval(int a,int b,int x,int k) // 区间修改 区间加值;
  32. {
  33. if(tree[k].l>=a && tree[k].r<=b ){
  34. if(tree[k].w==) tree[k].w=;
  35. else tree[k].w=;
  36. return;
  37. }
  38. int mid=(tree[k].l+tree[k].r)/;
  39. if(b<=mid) change_interval(a,b,x,*k);
  40. else if(a>=mid+) change_interval(a,b,x,*k+);
  41. else change_interval(a,mid,x,*k),change_interval(mid+,b,x,*k+);
  42. tree[k].w=tree[k*].w+tree[k*+].w;
  43. }
  44. int ask_interval(int a,int b,int k) // 区间查询
  45. {
  46. int num=;
  47. if(tree[k].l>=a&&tree[k].r<=b){
  48. num=tree[k].w;
  49. return num;
  50. }
  51. int mid=( tree[k].l+tree[k].r)/;
  52. if(b<=mid) num+=ask_interval(a,b,*k);
  53. else if(a>=mid+) num+=ask_interval(a,b,*k+);
  54. else num+=ask_interval(a,mid,*k)+ask_interval(mid+,b,*k+);
  55. return num;
  56. }
  57. char ch[];
  58. int c;
  59. int main(){
  60. int n; scanf("%d",&n);
  61. for(int i=;i<=n-;i++){
  62. int x,y; scanf("%d %d",&x,&y);ADD(x,y);
  63. }
  64. dfs(,);
  65. build(,n,);
  66. int q; scanf("%d",&q);
  67. while(q--){
  68. scanf("%s %d",ch,&c);
  69. if(ch[]=='Q') {
  70. printf("%d\n",ask_interval(pa[c].first,pa[c].second,));
  71. }
  72. else {
  73. change_interval(pa[c].first,pa[c].first,,);
  74. }
  75.  
  76. }
  77. }

dfs序列  主席树  hdu 5678

  1. #pragma GCC optimize(2)
  2. #pragma GCC optimize(3)
  3. #pragma GCC optimize(4)
  4. #include<bits/stdc++.h>
  5. #define ll long long
  6. using namespace std;
  7. const int maxn=4e5+;
  8. const int mod=1e9+;
  9. const int inv2=(+mod)/;
  10. int a[maxn],b[maxn];
  11. pair<int,int> pa[maxn];
  12. int head[maxn],cnt=;
  13. struct EDGE { int next,to; } edge[maxn];
  14. void ADD(int u,int v){
  15. edge[++cnt].next=head[u];
  16. edge[cnt].to=v;
  17. head[u]=cnt;
  18. }
  19. int tot=;
  20. void dfs(int x,int fa){
  21. pa[x].first=++tot; a[tot]=b[x];
  22. for(int i=head[x];i!=;i=edge[i].next){
  23. int u=edge[i].to;
  24. if(u==fa) continue;
  25. dfs(u,x);
  26. } pa[x].second=tot;
  27. }
  28.  
  29. int c[maxn*];
  30. int qqq[maxn*];
  31. int root[maxn],lson[maxn*],rson[maxn*],v[maxn*];
  32. void build(int &x,int l,int r){
  33. x=++tot; //cout<<x<<endl;
  34. if(l==r) { v[x]=; return; }
  35. int mid=(l+r)/;
  36. build(lson[x],l,mid);
  37. build(rson[x],mid+,r);
  38. v[x]=v[lson[x]]+v[rson[x]];
  39. }
  40. void update(int odd,int &x,int pos,int value,int l,int r){
  41. x=++tot; v[x]=v[odd]+value; lson[x]=lson[odd]; rson[x]=rson[odd]; // 构链
  42. if(l==r) { return ; }
  43. int mid=(l+r)/;
  44. if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
  45. else update(rson[odd],rson[x],pos,value,mid+,r);
  46. }
  47. int query(int odd,int x,int k,int l,int r){
  48. int num=v[lson[x]]-v[lson[odd]];
  49. if(l==r) return l;
  50. if(k<=num) return query(lson[odd],lson[x],k,l,(l+r)/);
  51. else return query(rson[odd],rson[x],k-num,(l+r)/+,r);
  52. }
  53.  
  54. inline int read(){
  55. int s=,w=;
  56. char ch=getchar();
  57. while(ch<''||ch>''){if(ch=='-')w=-;ch=getchar();}
  58. while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
  59. return s*w;
  60. }
  61. map<int,int> mp;
  62. vector<int> vs;
  63. int kkk[maxn];
  64. int main(){
  65. c[]=; for(int i=;i<maxn*;i++){ c[i]=1ll*c[i-]*%mod; }
  66. int T; T=read();
  67. while(T--){
  68. vs.clear();
  69. mp.clear();
  70. cnt=; tot=;
  71. int n,q; n=read(); q=read();
  72. for(int i=;i<=n;i++) b[i]=read();
  73. for(int i=;i<=n;i++) vs.push_back(b[i]);
  74. sort(vs.begin(),vs.end());
  75. vs.erase(unique(vs.begin(),vs.end()),vs.end());
  76. for(int i=;i<vs.size();i++) { mp[vs[i]]=i+; kkk[i+]=vs[i]; }
  77. for(int i=;i<=n;i++) b[i]=mp[b[i]];
  78. for(int i=;i<=n-;i++) { int x,y; x=read(); y=read(); ADD(x,y); }
  79. dfs(,);
  80. build(root[],,n);
  81. for(int i=;i<=n;i++){ update(root[i-],root[i],a[i],,,n); }
  82. ll ans=;
  83. double f=;
  84. for(int i=;i<=q;i++){
  85. int k; k=read();
  86. int r=pa[k].second;
  87. int l=pa[k].first;
  88. int d=(r-l+);
  89. if(d%==){
  90. int w=(d+)/;
  91. int temp;
  92. if(qqq[k]== ) { temp=kkk[query(root[l-],root[r],w,,n)]; qqq[k]=temp; }
  93. temp=qqq[k];
  94. ans+=1ll*temp*c[q-i]%mod;
  95. }
  96. else {
  97. int w=d/;
  98. int temp=;
  99. if(qqq[k]==){
  100. temp+=kkk[query(root[l-],root[r],w,,n)]+kkk[query(root[l-],root[r],w+,,n)];
  101. qqq[k]=temp;
  102. }
  103. temp=qqq[k];
  104. if(i==q){
  105. if(temp%==) f=0.5,ans+=temp/;
  106. else ans+=1ll*temp/%mod;
  107. }
  108. else {
  109. ans+=1ll*temp*%mod*c[q-i-]%mod;
  110. }
  111. }
  112. }
  113. f+=ans%mod;
  114. printf("%.1f\n",f);
  115. for(int i=;i<=n;i++){
  116. qqq[i]=; head[i]=; edge[i].next=; edge[i].to=;
  117. }
  118. }
  119. return ;
  120. }

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

  1. #pragma GCC optimize(2)
  2. #pragma GCC optimize(3)
  3. #pragma GCC optimize(4)
  4. #include<bits/stdc++.h>
  5. #define ll long long
  6. using namespace std;
  7. const int mod=1e9+;
  8. const int inv2=(+mod)/;
  9. int n,m;
  10. struct SAM
  11. {
  12. static const int MAXN = <<;//大小为字符串长度两倍
  13. static const int maxn = <<;
  14. static const int LetterSize = ;
  15. int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
  16. int num[maxn]; // 自动机->字符串结束位置
  17. int renum[maxn]; // 结束位置-> 自动机位置
  18. int num_0[maxn];
  19. void init( void){
  20. last = tot = ; len[] = ;
  21. memset( ch[], , sizeof ch[]);
  22. }
  23. void add( int x,int c) {
  24. int p = last, np = last = ++tot; num[tot]=c+; renum[c+]=tot; // 记录结束位置
  25. len[np] = len[p] + ;
  26. memset( ch[np], , sizeof ch[np]);
  27. while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
  28. if( p == ) fa[np] = ;
  29. else{
  30. int q = ch[p][x];
  31. if( len[q] == len[p] + ) fa[np] = q;
  32. else
  33. {
  34. int nq = ++tot;
  35. memcpy( ch[nq], ch[q], sizeof ch[q]);
  36. len[nq] = len[p] + , fa[nq] = fa[q], fa[q] = fa[np] = nq;
  37. while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p];
  38. }
  39. }
  40. }
  41. int root[maxn],lson[maxn*],rson[maxn*],v[maxn*];
  42. int w=;
  43. void build(int &x,int l,int r){
  44. x=++w; //cout<<x<<endl;
  45. if(l==r) { v[x]=; return; }
  46. int mid=(l+r)/;
  47. build(lson[x],l,mid);
  48. build(rson[x],mid+,r);
  49. v[x]=v[lson[x]]+v[rson[x]];
  50. }
  51. void update(int odd,int &x,int pos,int value,int l,int r){
  52. x=++w; v[x]=v[odd]+value; lson[x]=lson[odd]; rson[x]=rson[odd]; // ¹¹Á´
  53. if(l==r) { return ; }
  54. int mid=(l+r)/;
  55. if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
  56. else update(rson[odd],rson[x],pos,value,mid+,r);
  57. }
  58. int query(int odd,int x,int k,int l,int r){
  59. int num=v[lson[x]]-v[lson[odd]];
  60. if(l==r) return l;
  61. if(k<=num) return query(lson[odd],lson[x],k,l,(l+r)/);
  62. else return query(rson[odd],rson[x],k-num,(l+r)/+,r);
  63. }
  64. vector<int> vs[maxn];
  65. int bz[maxn][];
  66. int a[maxn]; //主席树上系列 -> 结束位置
  67. pair<int,int> pa[maxn]; // dfs 序列
  68. int k=;
  69. void dfs(int x,int fa){
  70. bz[x][]=fa; pa[x].first=++k; a[k]=num[x]; //
  71. for(int i=;i<=;i++) bz[x][i]=bz[bz[x][i-]][i-]; // 树上倍增
  72. for(int i=;i<vs[x].size();i++){ dfs(vs[x][i],x);num_0[x]+=num_0[vs[x][i]]; }
  73. pa[x].second=k;
  74. if(num[x]==) num_0[x]++;
  75.  
  76. }
  77. void make_tu(){
  78. for(int i=;i<=tot;i++) vs[fa[i]].push_back(i);dfs(,);
  79. }
  80. void make(){
  81. make_tu();
  82. build(root[],,tot);
  83. for(int i=;i<=tot;i++){ update(root[i-],root[i],a[i]+,,,tot+); }
  84. }
  85. void slove(){
  86. for(int i=;i<=m;i++){
  87. int l,r,k; scanf("%d %d %d",&l,&r,&k);
  88. int d=r-l+;
  89. int pos=renum[r];
  90. for(int i=;i>=;i--){
  91. if(len[bz[pos][i]]>=d) pos=bz[pos][i];
  92. }
  93. int lll=pa[pos].first;
  94. int rrr=pa[pos].second;
  95. int ddd=rrr-lll+;
  96. if(k+num_0[pos]>ddd){
  97. printf("-1\n");
  98. }
  99. else {
  100. int w=query(root[lll-],root[rrr],k+num_0[pos],,tot+);
  101. if(w==) printf("-1\n");
  102. else printf("%d\n",w-d);
  103. }
  104. }
  105. for(int i=;i<=tot+;i++){
  106. vs[i].clear(); num_0[i]=; num[i]=; renum[i]=;
  107. }
  108. k=;
  109. }
  110. }sam;
  111. char ss[];
  112. int main(){
  113. int T; scanf("%d",&T);
  114. while(T--){
  115. sam.init();
  116. scanf("%d %d",&n,&m); scanf("%s",ss);
  117. for(int i=;i<n;i++) sam.add(ss[i]-'a',i);
  118. sam.make();
  119. sam.slove();
  120. }
  121. return ;
  122. }
  1. #include<bits/stdc++.h>
  2. #define rank rk
  3. using namespace std;
  4. const int maxn = ;
  5. const int N=;
  6. const int M=N*;
  7. int sa[maxn], rank[maxn], height[maxn];
  8. int wa[maxn], wb[maxn], wv[maxn], cnt[maxn];
  9. void SA(int *r, int n, int m) {
  10. int *x = wa, *y = wb;
  11. for(int i = ; i < m; i++) cnt[i] = ;
  12. for(int i = ; i < n; i++) cnt[x[i] = r[i]]++;
  13. for(int i = ; i < m; i++) cnt[i] += cnt[i - ];
  14. for(int i = n - ; i >= ; i--) sa[--cnt[x[i]]] = i;
  15. for(int j = ; j < n; j <<= ) {
  16. int p = ;
  17. for(int i = n - j; i < n; i++) y[p++] = i;
  18. for(int i = ; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j;
  19. for(int i = ; i < n; i++) wv[i] = x[y[i]];
  20. for(int i = ; i < m; i++) cnt[i] = ;
  21. for(int i = ; i < n; i++) cnt[wv[i]]++;
  22. for(int i = ; i < m; i++) cnt[i] += cnt[i - ];
  23. for(int i = n - ; i >= ; i--) sa[--cnt[wv[i]]] = y[i];
  24. swap(x, y);
  25. p = ; x[sa[]] = ;
  26. for(int i = ; i < n; i++)
  27. x[sa[i]] = y[sa[i - ]] == y[sa[i]] && y[sa[i - ] + j] == y[sa[i] + j] ? p - : p++;
  28. if(p >= n) break;
  29. m = p;
  30. }
  31. }
  32. void calcHeight(int *r, int n) {
  33. int i, j, k;
  34. for(i = j = k = ; i < n; height[rank[i++]] = k)
  35. for(k ? k-- : , j = sa[rank[i] - ]; r[i + k] == r[j + k]; k++);
  36. }
  37. int n, s[maxn];
  38. int a[maxn];
  39. char str[maxn];
  40. int root[N],lson[M],rson[M],v[M];
  41. int tot=;
  42. void build(int &x,int l,int r){
  43. x=++tot; //cout<<x<<endl;
  44. if(l==r) { v[x]=; return; }
  45. int mid=(l+r)/;
  46. build(lson[x],l,mid);
  47. build(rson[x],mid+,r);
  48. v[x]=v[lson[x]]+v[rson[x]];
  49. }
  50. void update(int odd,int &x,int pos,int value,int l,int r){
  51. x=++tot; v[x]=v[odd]+value; lson[x]=lson[odd]; rson[x]=rson[odd]; // 构链
  52. if(l==r) { return ; }
  53. int mid=(l+r)/;
  54. if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
  55. else update(rson[odd],rson[x],pos,value,mid+,r);
  56. }
  57. int query(int odd,int x,int k,int l,int r){
  58. int num=v[lson[x]]-v[lson[odd]];
  59. if(l==r) return l;
  60. if(k<=num) return query(lson[odd],lson[x],k,l,(l+r)/);
  61. else return query(rson[odd],rson[x],k-num,(l+r)/+,r);
  62. }
  63. int lg[maxn];
  64. int st[maxn][];
  65. void make_ST(){
  66. for(int i=n;i>=;i--){
  67. st[i][]=height[i];
  68. for(int j=;i+(<<j-)-<=n;j++){
  69. st[i][j]=min(st[i][j-],st[i+(<<(j-))][j-]);
  70. }
  71. // cout<<st[i][0]<<endl;
  72. }
  73. }
  74. bool st_check(int l,int r,int d){
  75. if(l==r) return ;
  76. l++;
  77. int k=lg[r-l+];
  78. int m=min(st[l][k],st[r-(<<k)+][k]);
  79. if(m>=d) return ;
  80. else return ;
  81. }
  82. int check1(int l,int r,int d){
  83. int x=l;
  84. int mid=(l+r)/;
  85. while(l<r){
  86. if(st_check(x,mid,d)) l=mid;
  87. else r=mid-;
  88. mid=(l+r+)/;
  89. }
  90. return mid;
  91. }
  92. int check2(int l,int r,int d){
  93. int x=r;
  94. int mid=(l+r)/;
  95. while(l<r){
  96. // cout<<l<<" "<<r<<" "<<mid<<" "<<st_check(mid,x,d)<<endl;;
  97. if(st_check(mid,x,d)) r=mid;
  98. else l=mid+;
  99. mid=(l+r)/;
  100. }
  101. return mid;
  102. }
  103. void make(int l,int r,int k){
  104.  
  105. int d=(r-l+);
  106. int pos=rank[l-];
  107. int rr,ll;
  108. rr=check1(pos,n,d);
  109. ll=check2(,pos,d);
  110. int w=rr-ll+;
  111. if(w<k) printf("-1\n");
  112. else {
  113. int ans=query(root[ll-],root[rr],k,,n);
  114. printf("%d\n",ans);
  115. }
  116. }
  117. int main() {
  118. for(int i=;i<maxn;i++){lg[i]=lg[i>>]+;}
  119. int T; scanf("%d", &T);
  120. while(T--) {
  121. int q; scanf("%d %d",&n,&q);
  122. scanf("%s", str); n = strlen(str);
  123. for(int i = ; i < n; i++) s[i] = str[i]; s[n] = ;
  124. SA(s, n + , );
  125. for(int i = ; i <= n; i++) rank[sa[i]] = i;
  126. calcHeight(s, n);
  127. make_ST();
  128. int nn=n;
  129. build(root[],,nn);
  130. for(int i=;i<=n;i++) a[i]=sa[i]+;
  131. // for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
  132. for(int i=;i<=n;i++) update(root[i-],root[i],a[i],,,nn);
  133. while(q--){
  134. int l,r,k; scanf("%d %d %d",&l,&r,&k);
  135. make(l,r,k);
  136. }
  137. }
  138. return ;
  139. }

dfs序 线段树 dfs序列 主席树的更多相关文章

  1. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  2. BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)

    题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...

  3. POJ 3321 DFS序+线段树

    单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4:   5: #include < ...

  4. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

  5. Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...

  6. 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 130[Submit][Status][Discuss] D ...

  7. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  8. 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树

    题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...

  9. F - Change FZU - 2277 (DFS序+线段树)

    题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...

随机推荐

  1. java+实现文件的上传和下载

    项目截图 路径配置 将localhost:8080/up6全部替换为实际项目路径 使用mysql文件夹下的脚本创建数据表. 创建后可以在数据库中看到创建好的数据表 2.修改数据库连接 3.修改上传地址 ...

  2. 进程,虚拟环境,Mysql主从

    进程 查看进程 ps(类似windows任务管理器) man 1 ps # 查看命令文档 ps[options] 1 UNIX options, which may be grouped and mu ...

  3. golang(06)函数介绍

    原文链接 http://www.limerence2017.com/2019/09/11/golang11/#more 函数简介 函数是编程语言中不可缺少的部分,在golang这门语言中函数是一等公民 ...

  4. clientX和clientY属性需要注意的地方

    clientX和clientY为可视区鼠标的位置. 1. 随鼠标移动的div块[runjs] 当document有多个页面时,会出现问题.[runjs] 2. 解决方案:scrollTop, scro ...

  5. Qt输出中文乱码的问题

    /* 我遇到的情况: 文件编码为UTF-8.程序输输出中文位乱码. 解决方案: 1. 工具->选项->环境->语言: Chinese 2. 选项->文本编辑器->行为-& ...

  6. 通过id()函数学习python的数据存储以及引用方式

    id()函数是python的内置函数,用于获取对象的内存地址. 1.1 可以看出,33被存储在内存地址19877464上,对变量a赋值,实际上是将其指向存储着33的内存地址. 1.2 不仅是数字类型, ...

  7. 华为HCNA乱学Round 5:华为交换机基础

  8. 模仿Spy++抓某窗口消息

    核心函数 SetWindowsHookExA API文档:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-s ...

  9. Hanlp配置自定义词典遇到的问题与解决方法

    本文是整理了部分网友在配置hanlp自定义词典时遇到的一小部分问题,同时针对这些问题,也提供另一些解决的方案以及思路.这里分享给大家学习参考. 要使用hanlp加载自定义词典可以通过修改配置文件han ...

  10. MY TESTS

    励志整理所有的n次考试的博客: [五一qbxt]test1 [五一qbxt]test2 [校内test]桶哥的问题 [6.10校内test] noip模拟 6.12校内test [6.12校内test ...