一、 线段树
P2412 查单词 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P2412
解析:
板子题,区间搜索,不需要区间修改
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=1e5+10;
struct node
{string s,p;
}tr[4*N];
string k[N],kk[N];
void push_up (int u)
{string a=tr[u<<1].s,b=tr[u<<1|1].s;if (a>b) tr[u]=tr[u<<1];else tr[u]=tr[u<<1|1];
}
node push_up(node l,node r)
{string a=l.s,b=r.s;if (a>b) return l;return r;
}
void build (int u,int l,int r)
{if (l==r){tr[u].p=k[l],tr[u].s=kk[l];return ;}int mid=l+r>>1;build (u<<1,l,mid), build (u<<1|1,mid+1,r);push_up(u);
}
node query(int L,int R,int u,int l,int r)
{if (l>=L&&r<=R) return tr[u];int mid=l+r>>1;node res;if (L<=mid&&mid<R) res=push_up(query(L,R,u<<1,l,mid),query(L,R,u<<1|1,mid+1,r));else if (L<=mid) res=query(L,R,u<<1,l,mid);else if (mid<R) res=query(L,R,u<<1|1,mid+1,r);return res;
}
int n,m;
void solve()
{cin>>n>>m;for (int i=1;i<=n;i++){cin>>k[i];string s;for (int j=0;j<k[i].size();j++){if (k[i][j]>='A'&&k[i][j]<='Z') s +=k[i][j]+32;else s +=k[i][j];}kk[i]=s;}build (1,1,n);for (int i=1;i<=m;i++){int l,r;cin>>l>>r;cout<<query(l,r,1,1,n).p<<endl;}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;//cin >> T;while (T--) solve();return 0;
}
二、树状数组(也可用线段树)
P5057 [CQOI2006] 简单题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P5057解析:
只需要单点查询和区间修改,是否存在用 &1判断
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=1e6+10;
int tr[N];
int n,m;
int lowbit(int x)
{return x&-x;
}
void add(int x,int c)
{for (int i=x;i<=n;i +=lowbit(i)) tr[i] +=c;
}
int query(int x)
{int ans=0;for (int i=x;i>0;i -=lowbit(i)) ans +=tr[i];return ans;
}
void solve()
{cin>>n>>m;int op,l,r,x;for (int i=1;i<=m;i++){cin>>op;if (op==1){cin>>l>>r;add(l,1),add(r+1,-1);}else {cin>>x;cout<<(query(x)&1)<<endl;}}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;//cin >> T;while (T--) solve();return 0;
}
三、线段树
P8856 [POI2002] 火车线路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P8856解析:
显然,我们可以把这道题转换成数列区间最小值的问题,然后用线段树。
我们每处理一个预定,如果可以满足,即这一段区间里所有的数都大于等于预定的数,那么我们就把区间里的所有数都减去这个数。否则的话就是不能满足。
需要push_down操作。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=1e6+10;
struct node
{int mi;
}tr[4*N];
int mark[N];
void push_up (int u)
{tr[u].mi=min(tr[u<<1].mi,tr[u<<1|1].mi);
}
void push_down (int u,int l,int r)
{int mid=l+r>>1;tr[u<<1].mi +=mark[u];tr[u<<1|1].mi +=mark[u];mark[u<<1] +=mark[u];mark[u<<1|1] +=mark[u];mark[u]=0;
}
void build (int u,int l,int r,int R)
{if (l==r){tr[u].mi=R;return ;}int mid=l+r>>1;build (u<<1,l,mid,R),build (u<<1|1,mid+1,r,R);push_up(u);
}
int query (int L,int R,int u,int l,int r)
{if (l>=L&&r<=R) return tr[u].mi;push_down(u,l,r);int mid=l+r>>1;int res=0;if (L<=mid&&mid<R) res=min(query(L,R,u<<1,l,mid),query(L,R,u<<1|1,mid+1,r));else if (L<=mid) res=query(L,R,u<<1,l,mid);else if (mid<R) res=query(L,R,u<<1|1,mid+1,r);return res;
}
void modify (int L,int R,int d,int u,int l,int r)
{if (l>=L&&r<=R) {tr[u].mi +=d;mark[u] +=d;return ;}push_down(u,l,r);int mid=l+r>>1;if (L<=mid) modify(L,R,d,u<<1,l,mid);if (mid<R) modify(L,R,d,u<<1|1,mid+1,r);push_up(u);
}
void solve()
{int n,R,c;cin>>n>>R>>c;build (1,1,n,R);while (c--){int o,d,m;cin>>o>>d>>m;int k=query(o,d-1,1,1,n);if (k>=m){cout<<"T\n";modify(o,d-1,-m,1,1,n);}else cout<<"N\n";}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;//cin >> T;while (T--) solve();return 0;
}
四、线段树+差分
P1438 无聊的数列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1438解析:
令等差序列的首项为 s,末项为 e,公差为 d。
如果要在差分序列上加一个等差序列,就要在a[l]加上s,a[l+1]~a[r]加上d,a[r+1]减去e。
线段树维护的是差分序列,单点查询 x 就是 1~x 的前缀和。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=2e5+10;
struct node
{int sum;
}tr[4*N];
int mark[4*N];
int n,m;
int a[N],b[N];
void push_up(int u)
{tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void push_down(int u,int l,int r)
{int mid=l+r>>1;tr[u<<1].sum +=mark[u]*(mid-l+1);tr[u<<1|1].sum +=mark[u]*(r-mid);mark[u<<1] +=mark[u];mark[u<<1|1] +=mark[u];mark[u]=0;
}
void build (int u,int l,int r)
{if (l==r){tr[u].sum=b[l];return ;}int mid=l+r>>1;build(u<<1,l,mid), build(u<<1|1,mid+1,r);push_up(u);
}
void modify(int L,int R,int d,int u,int l,int r)
{if (l>=L&&r<=R) {tr[u].sum +=(r-l+1)*d;mark[u] +=d;return ;}push_down(u,l,r);int mid=l+r>>1;if (L<=mid) modify(L,R,d,u<<1,l,mid);if (mid<R) modify(L,R,d,u<<1|1,mid+1,r);push_up(u);
}
int query(int L,int R,int u,int l,int r)
{if (l>=L&&r<=R) return tr[u].sum;push_down(u,l,r);int mid=l+r>>1;int res=0;if (L<=mid&&mid<R){res=query(L,R,u<<1,l,mid)+query(L,R,u<<1|1,mid+1,r);}else if (L<=mid) res=query(L,R,u<<1,l,mid);else if (mid<R) res=query(L,R,u<<1|1,mid+1,r);return res;
}
void solve()
{cin>>n>>m;for (int i=1;i<=n;i++) cin>>a[i];for (int i=1;i<=n;i++) b[i]=a[i]-a[i-1];build (1,1,n);for (int i=1;i<=m;i++){int op,l,r,k,d,x;cin>>op;if (op==1){cin>>l>>r>>k>>d;modify(l,l,k,1,1,n);if (l<r) modify(l+1,r,d,1,1,n);if (r<n) modify(r+1,r+1,-(k+(r-l)*d),1,1,n);}else {cin>>x;cout<<query(1,x,1,1,n)<<endl;}}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;// cin >> T;while (T--) solve();return 0;
}
五、线段树
P1198 [JSOI2008] 最大数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1198解析:
板子题,看代码,也不需要push_down操作。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
// int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
// typedef unsigned long long ULL;
// typedef pair<int, int> PII;
// const double PI = acos(-1.0);
const int N=2e5+10;
struct node
{int ma;
}tr[4*N];
void push_up(int u)
{tr[u].ma=max(tr[u<<1].ma,tr[u<<1|1].ma);
}
void modify(int x,int d,int u,int l,int r)
{if (l==x&&x==r){tr[u].ma=d;return ;}int mid=l+r>>1;if (x<=mid) modify(x,d,u<<1,l,mid);else modify(x,d,u<<1|1,mid+1,r);push_up(u);
}
int query(int L,int R,int u,int l,int r)
{if (l>=L&&r<=R) return tr[u].ma;int mid=l+r>>1;int res=-1e18;if (L<=mid&&mid<R) res=max(query(L,R,u<<1,l,mid),query(L,R,u<<1|1,mid+1,r));else if (L<=mid) res=query(L,R,u<<1,l,mid);else if (mid<R) res=query(L,R,u<<1|1,mid+1,r);return res;
}
int m,d;
void solve()
{cin>>m>>d;string s;int x;int n=0;int t=0;for (int i=1;i<=m;i++){cin>>s>>x;if (s=="A") {modify(n+1,(x+t)%d,1,1,m),n++;}else {cout<<query(n-x+1,n,1,1,m)<<endl;t=query(n-x+1,n,1,1,m);}}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int T = 1;//cin >> T;while (T--) solve();return 0;
}