dfs序 线段树 dfs序列 主席树
并查集
- #include<stdio.h>
- int stt[];
- void sset(int x)
- {
- for(int i=;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();
- /* */
- }
树状数组 (一般单点修改 区间查询)
- #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+;
- 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=;
- while(x)
- {
- sum+=a[x];
- x-=lowbit(x);
- }
- return sum;
- }
- int32_t main()
- {
- int q; cin>>n>>q;
- for(int i=;i<=n;i++)
- {
- int x; cin>>x;
- update(i,x);
- }
- while(q--)
- {
- int x,b,c;
- cin>>x>>b>>c;
- if(x==) {update(b,c);}
- if(x==)
- {
- cout<<getsum(c)-getsum(b-)<<endl;
- }
- }
- }
- 区间求值
一个其他学法的数组数组
- #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+;
- 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=;;
- while(x<=n)
- {
- sum+=a[x]; x+=lowbit(x);
- }return sum;
- }
- int main()
- {
- ios::sync_with_stdio(false); cin.tie(); cout.tie();
- int q; cin>>n>>q;
- for(int i=;i<=n;i++)
- {
- int x; cin>>x; update(i,x); update(i-,-x);
- }
- while(q--)
- {
- int x;cin>>x;
- if(x==) { int a,b,c; cin>>a>>b>>c; update(b,c); update(a-,-c);}
- if(x==) { int a; cin>>a; cout<<getsum(a)<<endl;}
- }
- }
- 求点的值
线段树 模板
- #include<bits/stdc++.h>
- #define int long long
- using namespace std;
- const int maxn=1e5+;
- struct NODE
- {
- int l,r,w,f; // f 为lazy标记
- }tree[*maxn+];
- 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 )/;
- build(p,mid,*k);
- build(mid+,q,*k+);
- tree[k].w=tree[*k].w+tree[*k+].w;
- }
- void down(int k) // (lazy 标记) (××××) (important)
- {
- tree[*k].f+=tree[k].f;
- tree[*k+].f+=tree[k].f;
- tree[k*].w+=tree[k].f*(tree[k*].r-tree[k*].l+);
- tree[k*+].w+=tree[k].f*(tree[k*+].r-tree[k*+].l+);
- tree[k].f=;
- }
- 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+)*x;
- tree[k].f+=x;
- return;
- }
- if(tree[k].f) down(k);
- int mid=(tree[k].l+tree[k].r)/;
- if(b<=mid) change_interval(a,b,x,*k);
- else if(a>=mid+) change_interval(a,b,x,*k+);
- else change_interval(a,mid,x,*k),change_interval(mid+,b,x,*k+);
- tree[k].w=tree[k*].w+tree[k*+].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)/;
- if(x<=mid) change_point(x,*k);
- else change_point(x,*k+);
- tree[k].w=tree[k*].w+tree[k*+].w;
- }
- int ask_interval(int a,int b,int k) // 区间查询
- {
- int num=;
- 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)/;
- if(b<=mid) num+=ask_interval(a,b,*k);
- else if(a>=mid+) num+=ask_interval(a,b,*k+);
- else num+=ask_interval(a,mid,*k)+ask_interval(mid+,b,*k+);
- return num;
- }
- int ask_point(int x,int k) // 点查询
- {
- int num=;
- 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)/;
- if(x<=mid) ask_point(x,*k);
- if(x>=mid+) ask_point(x,*k+);
- }
- int32_t main()
- {
- }
主席树 模板 hdu 2665
- #include<bits/stdc++.h>
- using namespace std;
- const int N=;
- const int M=*;
- int root[N],lson[M],rson[M],v[M];
- int a[N],b[N];
- int tot=;
- 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]=; return; }
- int mid=(l+r)/;
- build(lson[x],l,mid);
- build(rson[x],mid+,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)/;
- if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
- else update(rson[odd],rson[x],pos,value,mid+,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)/);
- else return query(rson[odd],rson[x],k-num,(l+r)/+,r);
- }
- int main(){
- int T; scanf("%d",&T);
- while(T--){
- int n,m; scanf("%d %d",&n,&m);
- for(int i=;i<=n;i++) scanf("%d",&a[i]);
- for(int i=;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=;i<vs.size();i++) mp[vs[i]]=i+,b[i+]=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[],,nn);
- for(int i=;i<=n;i++){
- int pos=mp[a[i]]; //cout<<mp[a[i]]<<endl;
- update(root[i-],root[i],pos,,,nn);
- }
- for(int i=;i<=m;i++){
- int l,r,k; scanf("%d %d %d",&l,&r,&k);
- int ans=query(root[l-],root[r],k,,nn);
- printf("%d\n",b[ans]);
- }
- vs.clear();
- mp.clear();
- for(int i=;i<=n;i++) root[i]=;
- tot=;
- }
- }
dfs 线段树 poj3321
- #include<cstdio>
- #include<vector>
- using namespace std;
- const int maxn=1e5+;
- pair<int,int> pa[maxn];
- int head[maxn],cnt=;
- 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=;
- void dfs(int x,int fa){
- pa[x].first=++tot;
- for(int i=head[x];i!=;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[*maxn+];
- 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=; return ; }
- int mid=( tree[k].l+tree[k].r )/;
- build(p,mid,*k); build(mid+,q,*k+);
- tree[k].w=tree[*k].w+tree[*k+].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==) tree[k].w=;
- else tree[k].w=;
- return;
- }
- int mid=(tree[k].l+tree[k].r)/;
- if(b<=mid) change_interval(a,b,x,*k);
- else if(a>=mid+) change_interval(a,b,x,*k+);
- else change_interval(a,mid,x,*k),change_interval(mid+,b,x,*k+);
- tree[k].w=tree[k*].w+tree[k*+].w;
- }
- int ask_interval(int a,int b,int k) // 区间查询
- {
- int num=;
- if(tree[k].l>=a&&tree[k].r<=b){
- num=tree[k].w;
- return num;
- }
- int mid=( tree[k].l+tree[k].r)/;
- if(b<=mid) num+=ask_interval(a,b,*k);
- else if(a>=mid+) num+=ask_interval(a,b,*k+);
- else num+=ask_interval(a,mid,*k)+ask_interval(mid+,b,*k+);
- return num;
- }
- char ch[];
- int c;
- int main(){
- int n; scanf("%d",&n);
- for(int i=;i<=n-;i++){
- int x,y; scanf("%d %d",&x,&y);ADD(x,y);
- }
- dfs(,);
- build(,n,);
- int q; scanf("%d",&q);
- while(q--){
- scanf("%s %d",ch,&c);
- if(ch[]=='Q') {
- printf("%d\n",ask_interval(pa[c].first,pa[c].second,));
- }
- else {
- change_interval(pa[c].first,pa[c].first,,);
- }
- }
- }
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+;
- const int mod=1e9+;
- const int inv2=(+mod)/;
- int a[maxn],b[maxn];
- pair<int,int> pa[maxn];
- int head[maxn],cnt=;
- 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=;
- void dfs(int x,int fa){
- pa[x].first=++tot; a[tot]=b[x];
- for(int i=head[x];i!=;i=edge[i].next){
- int u=edge[i].to;
- if(u==fa) continue;
- dfs(u,x);
- } pa[x].second=tot;
- }
- int c[maxn*];
- int qqq[maxn*];
- int root[maxn],lson[maxn*],rson[maxn*],v[maxn*];
- void build(int &x,int l,int r){
- x=++tot; //cout<<x<<endl;
- if(l==r) { v[x]=; return; }
- int mid=(l+r)/;
- build(lson[x],l,mid);
- build(rson[x],mid+,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)/;
- if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
- else update(rson[odd],rson[x],pos,value,mid+,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)/);
- else return query(rson[odd],rson[x],k-num,(l+r)/+,r);
- }
- inline int read(){
- int s=,w=;
- char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')w=-;ch=getchar();}
- while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
- return s*w;
- }
- map<int,int> mp;
- vector<int> vs;
- int kkk[maxn];
- int main(){
- c[]=; for(int i=;i<maxn*;i++){ c[i]=1ll*c[i-]*%mod; }
- int T; T=read();
- while(T--){
- vs.clear();
- mp.clear();
- cnt=; tot=;
- int n,q; n=read(); q=read();
- for(int i=;i<=n;i++) b[i]=read();
- for(int i=;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=;i<vs.size();i++) { mp[vs[i]]=i+; kkk[i+]=vs[i]; }
- for(int i=;i<=n;i++) b[i]=mp[b[i]];
- for(int i=;i<=n-;i++) { int x,y; x=read(); y=read(); ADD(x,y); }
- dfs(,);
- build(root[],,n);
- for(int i=;i<=n;i++){ update(root[i-],root[i],a[i],,,n); }
- ll ans=;
- double f=;
- for(int i=;i<=q;i++){
- int k; k=read();
- int r=pa[k].second;
- int l=pa[k].first;
- int d=(r-l+);
- if(d%==){
- int w=(d+)/;
- int temp;
- if(qqq[k]== ) { temp=kkk[query(root[l-],root[r],w,,n)]; qqq[k]=temp; }
- temp=qqq[k];
- ans+=1ll*temp*c[q-i]%mod;
- }
- else {
- int w=d/;
- int temp=;
- if(qqq[k]==){
- temp+=kkk[query(root[l-],root[r],w,,n)]+kkk[query(root[l-],root[r],w+,,n)];
- qqq[k]=temp;
- }
- temp=qqq[k];
- if(i==q){
- if(temp%==) f=0.5,ans+=temp/;
- else ans+=1ll*temp/%mod;
- }
- else {
- ans+=1ll*temp*%mod*c[q-i-]%mod;
- }
- }
- }
- f+=ans%mod;
- printf("%.1f\n",f);
- for(int i=;i<=n;i++){
- qqq[i]=; head[i]=; edge[i].next=; edge[i].to=;
- }
- }
- return ;
- }
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+;
- const int inv2=(+mod)/;
- int n,m;
- struct SAM
- {
- static const int MAXN = <<;//大小为字符串长度两倍
- static const int maxn = <<;
- static const int LetterSize = ;
- 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 = ; len[] = ;
- memset( ch[], , sizeof ch[]);
- }
- void add( int x,int c) {
- int p = last, np = last = ++tot; num[tot]=c+; renum[c+]=tot; // 记录结束位置
- len[np] = len[p] + ;
- memset( ch[np], , sizeof ch[np]);
- while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
- if( p == ) fa[np] = ;
- else{
- int q = ch[p][x];
- if( len[q] == len[p] + ) fa[np] = q;
- else
- {
- int nq = ++tot;
- memcpy( ch[nq], ch[q], sizeof ch[q]);
- len[nq] = len[p] + , 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*],rson[maxn*],v[maxn*];
- int w=;
- void build(int &x,int l,int r){
- x=++w; //cout<<x<<endl;
- if(l==r) { v[x]=; return; }
- int mid=(l+r)/;
- build(lson[x],l,mid);
- build(rson[x],mid+,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)/;
- if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
- else update(rson[odd],rson[x],pos,value,mid+,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)/);
- else return query(rson[odd],rson[x],k-num,(l+r)/+,r);
- }
- vector<int> vs[maxn];
- int bz[maxn][];
- int a[maxn]; //主席树上系列 -> 结束位置
- pair<int,int> pa[maxn]; // dfs 序列
- int k=;
- void dfs(int x,int fa){
- bz[x][]=fa; pa[x].first=++k; a[k]=num[x]; //
- for(int i=;i<=;i++) bz[x][i]=bz[bz[x][i-]][i-]; // 树上倍增
- for(int i=;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]==) num_0[x]++;
- }
- void make_tu(){
- for(int i=;i<=tot;i++) vs[fa[i]].push_back(i);dfs(,);
- }
- void make(){
- make_tu();
- build(root[],,tot);
- for(int i=;i<=tot;i++){ update(root[i-],root[i],a[i]+,,,tot+); }
- }
- void slove(){
- for(int i=;i<=m;i++){
- int l,r,k; scanf("%d %d %d",&l,&r,&k);
- int d=r-l+;
- int pos=renum[r];
- for(int i=;i>=;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+;
- if(k+num_0[pos]>ddd){
- printf("-1\n");
- }
- else {
- int w=query(root[lll-],root[rrr],k+num_0[pos],,tot+);
- if(w==) printf("-1\n");
- else printf("%d\n",w-d);
- }
- }
- for(int i=;i<=tot+;i++){
- vs[i].clear(); num_0[i]=; num[i]=; renum[i]=;
- }
- k=;
- }
- }sam;
- char ss[];
- int main(){
- int T; scanf("%d",&T);
- while(T--){
- sam.init();
- scanf("%d %d",&n,&m); scanf("%s",ss);
- for(int i=;i<n;i++) sam.add(ss[i]-'a',i);
- sam.make();
- sam.slove();
- }
- return ;
- }
- #include<bits/stdc++.h>
- #define rank rk
- using namespace std;
- const int maxn = ;
- const int N=;
- const int M=N*;
- 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 = ; i < m; i++) cnt[i] = ;
- for(int i = ; i < n; i++) cnt[x[i] = r[i]]++;
- for(int i = ; i < m; i++) cnt[i] += cnt[i - ];
- for(int i = n - ; i >= ; i--) sa[--cnt[x[i]]] = i;
- for(int j = ; j < n; j <<= ) {
- int p = ;
- for(int i = n - j; i < n; i++) y[p++] = i;
- for(int i = ; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j;
- for(int i = ; i < n; i++) wv[i] = x[y[i]];
- for(int i = ; i < m; i++) cnt[i] = ;
- for(int i = ; i < n; i++) cnt[wv[i]]++;
- for(int i = ; i < m; i++) cnt[i] += cnt[i - ];
- for(int i = n - ; i >= ; i--) sa[--cnt[wv[i]]] = y[i];
- swap(x, y);
- p = ; x[sa[]] = ;
- for(int i = ; i < n; i++)
- x[sa[i]] = y[sa[i - ]] == y[sa[i]] && y[sa[i - ] + j] == y[sa[i] + j] ? p - : p++;
- if(p >= n) break;
- m = p;
- }
- }
- void calcHeight(int *r, int n) {
- int i, j, k;
- for(i = j = k = ; i < n; height[rank[i++]] = k)
- for(k ? k-- : , j = sa[rank[i] - ]; 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=;
- void build(int &x,int l,int r){
- x=++tot; //cout<<x<<endl;
- if(l==r) { v[x]=; return; }
- int mid=(l+r)/;
- build(lson[x],l,mid);
- build(rson[x],mid+,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)/;
- if(mid>=pos) update(lson[odd],lson[x],pos,value,l,mid);
- else update(rson[odd],rson[x],pos,value,mid+,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)/);
- else return query(rson[odd],rson[x],k-num,(l+r)/+,r);
- }
- int lg[maxn];
- int st[maxn][];
- void make_ST(){
- for(int i=n;i>=;i--){
- st[i][]=height[i];
- for(int j=;i+(<<j-)-<=n;j++){
- st[i][j]=min(st[i][j-],st[i+(<<(j-))][j-]);
- }
- // cout<<st[i][0]<<endl;
- }
- }
- bool st_check(int l,int r,int d){
- if(l==r) return ;
- l++;
- int k=lg[r-l+];
- int m=min(st[l][k],st[r-(<<k)+][k]);
- if(m>=d) return ;
- else return ;
- }
- int check1(int l,int r,int d){
- int x=l;
- int mid=(l+r)/;
- while(l<r){
- if(st_check(x,mid,d)) l=mid;
- else r=mid-;
- mid=(l+r+)/;
- }
- return mid;
- }
- int check2(int l,int r,int d){
- int x=r;
- int mid=(l+r)/;
- while(l<r){
- // cout<<l<<" "<<r<<" "<<mid<<" "<<st_check(mid,x,d)<<endl;;
- if(st_check(mid,x,d)) r=mid;
- else l=mid+;
- mid=(l+r)/;
- }
- return mid;
- }
- void make(int l,int r,int k){
- int d=(r-l+);
- int pos=rank[l-];
- int rr,ll;
- rr=check1(pos,n,d);
- ll=check2(,pos,d);
- int w=rr-ll+;
- if(w<k) printf("-1\n");
- else {
- int ans=query(root[ll-],root[rr],k,,n);
- printf("%d\n",ans);
- }
- }
- int main() {
- for(int i=;i<maxn;i++){lg[i]=lg[i>>]+;}
- int T; scanf("%d", &T);
- while(T--) {
- int q; scanf("%d %d",&n,&q);
- scanf("%s", str); n = strlen(str);
- for(int i = ; i < n; i++) s[i] = str[i]; s[n] = ;
- SA(s, n + , );
- for(int i = ; i <= n; i++) rank[sa[i]] = i;
- calcHeight(s, n);
- make_ST();
- int nn=n;
- build(root[],,nn);
- for(int i=;i<=n;i++) a[i]=sa[i]+;
- // for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl;
- for(int i=;i<=n;i++) update(root[i-],root[i],a[i],,,nn);
- while(q--){
- int l,r,k; scanf("%d %d %d",&l,&r,&k);
- make(l,r,k);
- }
- }
- return ;
- }
dfs序 线段树 dfs序列 主席树的更多相关文章
- dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
4448: [Scoi2015]情报传递 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 588 Solved: 308[Submit][Status ...
- BZOJ2434 [Noi2011]阿狸的打字机(AC自动机 + fail树 + DFS序 + 线段树)
题目这么说的: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: 输入小 ...
- POJ 3321 DFS序+线段树
单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4: 5: #include < ...
- CodeForces 877E DFS序+线段树
CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
- F - Change FZU - 2277 (DFS序+线段树)
题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...
随机推荐
- java+实现文件的上传和下载
项目截图 路径配置 将localhost:8080/up6全部替换为实际项目路径 使用mysql文件夹下的脚本创建数据表. 创建后可以在数据库中看到创建好的数据表 2.修改数据库连接 3.修改上传地址 ...
- 进程,虚拟环境,Mysql主从
进程 查看进程 ps(类似windows任务管理器) man 1 ps # 查看命令文档 ps[options] 1 UNIX options, which may be grouped and mu ...
- golang(06)函数介绍
原文链接 http://www.limerence2017.com/2019/09/11/golang11/#more 函数简介 函数是编程语言中不可缺少的部分,在golang这门语言中函数是一等公民 ...
- clientX和clientY属性需要注意的地方
clientX和clientY为可视区鼠标的位置. 1. 随鼠标移动的div块[runjs] 当document有多个页面时,会出现问题.[runjs] 2. 解决方案:scrollTop, scro ...
- Qt输出中文乱码的问题
/* 我遇到的情况: 文件编码为UTF-8.程序输输出中文位乱码. 解决方案: 1. 工具->选项->环境->语言: Chinese 2. 选项->文本编辑器->行为-& ...
- 通过id()函数学习python的数据存储以及引用方式
id()函数是python的内置函数,用于获取对象的内存地址. 1.1 可以看出,33被存储在内存地址19877464上,对变量a赋值,实际上是将其指向存储着33的内存地址. 1.2 不仅是数字类型, ...
- 华为HCNA乱学Round 5:华为交换机基础
- 模仿Spy++抓某窗口消息
核心函数 SetWindowsHookExA API文档:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-s ...
- Hanlp配置自定义词典遇到的问题与解决方法
本文是整理了部分网友在配置hanlp自定义词典时遇到的一小部分问题,同时针对这些问题,也提供另一些解决的方案以及思路.这里分享给大家学习参考. 要使用hanlp加载自定义词典可以通过修改配置文件han ...
- MY TESTS
励志整理所有的n次考试的博客: [五一qbxt]test1 [五一qbxt]test2 [校内test]桶哥的问题 [6.10校内test] noip模拟 6.12校内test [6.12校内test ...