【知识】线段树!
线段树
P3372 【模板】线段树 1
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
#define int long long
inline int rd(){
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
#define rd rd()
void wt(int x){
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
wt(x / 10);
putchar(x % 10 + '0');
return;
}
void wt(char x){
putchar(x);
}
void wt(int x, char k){
wt(x),putchar(k);
}
namespace Star_F{
const int N = 100005;
struct node{
int l, r;
ll w, add;
} tr[N << 2];
ll a[N];
int n, m;
void pushup(int u){
tr[u].w = tr[u << 1].w + tr[u << 1 | 1].w;
}
void pushdown(int u){
if(tr[u].add){
tr[u << 1].add += tr[u].add, tr[u << 1].w += (tr[u << 1].r - tr[u << 1].l + 1) * tr[u].add;
tr[u << 1 | 1].add += tr[u].add, tr[u << 1 | 1].w += (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1) * tr[u].add;
}
tr[u].add = 0;
}
void build(int u,int l,int r){
tr[u].l = l, tr[u].r = r, tr[u].add = 0;
if(l==r){
tr[u].w = a[l];
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void update(int u,int l,int r,int k){
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].add += k;
tr[u].w += (tr[u].r - tr[u].l + 1) * k;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l<=mid)
update(u << 1, l, r, k);
if(r>mid)
update(u << 1 | 1, l, r, k);
pushup(u);
}
int query(int u,int l,int r){
if(tr[u].l>=l&&tr[u].r<=r)
return tr[u].w;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1, res = 0;
if(l<=mid)
res += query(u << 1, l, r);
if(r>mid)
res += query(u << 1 | 1, l, r);
return res;
}
void Main(){
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
build(1, 1, n);
while(m--){
int opt, x, y, k;
cin >> opt >> x >> y;
if(opt==1){
cin >> k;
update(1, x, y, k);
}
else{
cout << query(1, x, y) << endl;
}
}
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ClockA;
int T=1;
// T=rd;
while(T--) Star_F::Main();
// ClockB;
return 0;
}
/*
* ▀▀▀██████▄▄▄ _______________
* ▄▄▄▄▄ █████████▄ / \
* ▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Code has no BUG! |
* ▀▀█████▄▄ ▀██████▄██ | _________________/
* ▀▄▄▄▄▄ ▀▀█▄▀█════█▀ |/
* ▀▀▀▄ ▀▀███ ▀ ▄▄
* ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌ ______________________________
* ██▀▄▄▄██▀▄███▀ ▀▀████ ▄██ █ \\
* ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███ ▌▄▄▀▀▀▀█_____________________________ //
* ▌ ▐▀████▐███▒▒▒▒▒▐██▌
* ▀▄▄▄▄▀ ▀▀████▒▒▒▒▄██▀
* ▀▀█████████▀
* ▄▄██▀██████▀█
* ▄██▀ ▀▀▀ █
* ▄█ ▐▌
* ▄▄▄▄█▌ ▀█▄▄▄▄▀▀▄
* ▌ ▐ ▀▀▄▄▄▀
* ▀▀▄▄▀ ██
* \ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
* \- ▌ Name: Star_F ▀ ▀
* - ▌ (o) ▀
* /- ▌ Go Go Go ! ▀ ▀
* / ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
*/
P3373 【模板】线段树 2
多加了一个区间乘法,考虑多增加一个 pushdown
的时候要先算乘法后算加法,其他与模板一样
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
#define int long long
inline int rd(){
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
#define rd rd()
void wt(int x){
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
wt(x / 10);
putchar(x % 10 + '0');
return;
}
void wt(char x){
putchar(x);
}
void wt(int x, char k){
wt(x),putchar(k);
}
namespace Star_F{
const int N = 100005;
struct node{
int l, r;
int w, add, mul;
} tr[N << 2];
int a[N];
int n, q, m;
void pushup(int u){
tr[u].w = tr[u << 1].w + tr[u << 1 | 1].w;
}
void pushdown(int u){
if(tr[u].mul!=1){
tr[u << 1].mul *= tr[u].mul, tr[u << 1].add *= tr[u].mul, tr[u << 1].w *= tr[u].mul;
tr[u << 1 | 1].mul *= tr[u].mul, tr[u << 1 | 1].add *= tr[u].mul, tr[u << 1 | 1].w *= tr[u].mul;
}
if(tr[u].add!=0){
tr[u << 1].add += tr[u].add, tr[u << 1].w += (tr[u << 1].r - tr[u << 1].l + 1) * tr[u].add;
tr[u << 1 | 1].add += tr[u].add, tr[u << 1 | 1].w += (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1) * tr[u].add;
}
tr[u].mul = 1, tr[u].add = 0;
tr[u << 1].w %= m, tr[u << 1].mul %= m, tr[u << 1].add %= m;
tr[u << 1 | 1].w %= m, tr[u << 1 | 1].mul %= m, tr[u << 1 | 1].add %= m;
}
void build(int u,int l,int r){
tr[u].l = l, tr[u].r = r, tr[u].add = 0, tr[u].mul = 1;
if(l==r){
tr[u].w = a[l];
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void update1(int u,int l,int r,int k){
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].w = tr[u].w * k % m;
tr[u].add = tr[u].add * k % m;
tr[u].mul = tr[u].mul * k;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l<=mid)
update1(u << 1, l, r, k);
if(r>mid)
update1(u << 1 | 1, l, r, k);
pushup(u);
}
void update2(int u,int l,int r,int k){
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].add = (tr[u].add + k) % m;
tr[u].w = (tr[u].w + (tr[u].r - tr[u].l + 1) * k) % m;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l<=mid)
update2(u << 1, l, r, k);
if(r>mid)
update2(u << 1 | 1, l, r, k);
pushup(u);
}
int query(int u,int l,int r){
if(tr[u].l>=l&&tr[u].r<=r){
return tr[u].w;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1, res = 0;
if(l<=mid)
res = (res + query(u << 1, l, r)) % m;
if(r>mid)
res = (res + query(u << 1 | 1, l, r)) % m;
return res;
}
void Main(){
cin >> n >> q >> m;
for (int i = 1; i <= n;i++)
cin >> a[i];
build(1, 1, n);
while(q--){
int opt, x, y, k;
cin >> opt >> x >> y;
if(opt==1){
cin >> k;
update1(1, x, y, k);
}
else if(opt==2){
cin >> k;
update2(1, x, y, k);
}
else{
cout << query(1,x, y) << endl;
}
}
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ClockA;
int T=1;
// T=rd;
while(T--) Star_F::Main();
// ClockB;
return 0;
}
/*
* ▀▀▀██████▄▄▄ _______________
* ▄▄▄▄▄ █████████▄ / \
* ▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Code has no BUG! |
* ▀▀█████▄▄ ▀██████▄██ | _________________/
* ▀▄▄▄▄▄ ▀▀█▄▀█════█▀ |/
* ▀▀▀▄ ▀▀███ ▀ ▄▄
* ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌ ______________________________
* ██▀▄▄▄██▀▄███▀ ▀▀████ ▄██ █ \\
* ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███ ▌▄▄▀▀▀▀█_____________________________ //
* ▌ ▐▀████▐███▒▒▒▒▒▐██▌
* ▀▄▄▄▄▀ ▀▀████▒▒▒▒▄██▀
* ▀▀█████████▀
* ▄▄██▀██████▀█
* ▄██▀ ▀▀▀ █
* ▄█ ▐▌
* ▄▄▄▄█▌ ▀█▄▄▄▄▀▀▄
* ▌ ▐ ▀▀▄▄▄▀
* ▀▀▄▄▀ ██
* \ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
* \- ▌ Name: Star_F ▀ ▀
* - ▌ (o) ▀
* /- ▌ Go Go Go ! ▀ ▀
* / ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
*/
P1712 [NOI2016] 区间
首先
然后按照区间长度
如何判断一个点的覆盖次数呢?用线段树进行区间加,求根节点的max
即可。
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
#define int long long
inline int rd(){
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
#define rd rd()
void wt(int x){
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
wt(x / 10);
putchar(x % 10 + '0');
return;
}
void wt(char x){
putchar(x);
}
void wt(int x, char k){
wt(x),putchar(k);
}
namespace Star_F{
const int N = 1000005;
int v[N << 1], cnt;
int n, m;
struct node{
int l, r, len;
} f[N];
struct Tree{
int l, r;
int w, add, mx, posx;
}tr[N<<2];
bool cmp(node a,node b){
return a.len < b.len;
}
void build(int u,int l,int r){
tr[u].l = l, tr[u].r = r, tr[u].posx = l;
if(l==r)
return;
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}
void pushup(int u){
tr[u].mx = max(tr[u << 1].mx, tr[u << 1 | 1].mx);
}
void pushdown(int u){
if(tr[u].add){
tr[u << 1].add += tr[u].add, tr[u << 1].mx += tr[u].add;
tr[u << 1 | 1].add += tr[u].add, tr[u << 1 | 1].mx += tr[u].add;
}
tr[u].add = 0;
}
void update(int u,int l,int r,int k){
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].mx += k;
tr[u].add += k;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l<=mid)
update(u << 1, l, r, k);
if(r>mid)
update(u << 1 | 1, l, r, k);
pushup(u);
}
void Main(){
cin >> n >> m;
for (int i = 1; i <= n;i++){
cin >> f[i].l >> f[i].r;
f[i].len = f[i].r - f[i].l;
v[++cnt] = f[i].l, v[++cnt] = f[i].r;
}
sort(v + 1, v + cnt + 1);
int x = unique(v + 1, v + cnt + 1) - v - 1;
for (int i = 1; i <= n;i++){
f[i].l = lower_bound(v + 1, v + x + 1, f[i].l) - v;
f[i].r = lower_bound(v + 1, v + x + 1, f[i].r) - v;
}
sort(f + 1, f + n + 1, cmp);
build(1, 1, x);
int fr = 1, ans = 0x3f3f3f3f;
for (int i = 1; i <= n;i++){
update(1, f[i].l, f[i].r, 1);
while(tr[1].mx>=m){
ans = min(ans, f[i].len - f[fr].len);
update(1, f[fr].l, f[fr].r, -1);
fr++;
}
}
if(ans==0x3f3f3f3f)
cout << -1 << endl;
else
cout << ans << endl;
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ClockA;
int T=1;
// T=rd;
while(T--) Star_F::Main();
// ClockB;
return 0;
}
/*
* ▀▀▀██████▄▄▄ _______________
* ▄▄▄▄▄ █████████▄ / \
* ▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Code has no BUG! |
* ▀▀█████▄▄ ▀██████▄██ | _________________/
* ▀▄▄▄▄▄ ▀▀█▄▀█════█▀ |/
* ▀▀▀▄ ▀▀███ ▀ ▄▄
* ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌ ______________________________
* ██▀▄▄▄██▀▄███▀ ▀▀████ ▄██ █ \\
* ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███ ▌▄▄▀▀▀▀█_____________________________ //
* ▌ ▐▀████▐███▒▒▒▒▒▐██▌
* ▀▄▄▄▄▀ ▀▀████▒▒▒▒▄██▀
* ▀▀█████████▀
* ▄▄██▀██████▀█
* ▄██▀ ▀▀▀ █
* ▄█ ▐▌
* ▄▄▄▄█▌ ▀█▄▄▄▄▀▀▄
* ▌ ▐ ▀▀▄▄▄▀
* ▀▀▄▄▀ ██
* \ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
* \- ▌ Name: Star_F ▀ ▀
* - ▌ (o) ▀
* /- ▌ Go Go Go ! ▀ ▀
* / ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
*/
P4145 上帝造题的七分钟 2 / 花神游历各国
观察到每个数不会被开平方多次,于是可以暴力修改,对于一个区间,如果最大值为
线段树维护区间 max
即可。
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
#define int long long
inline int rd(){
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
#define rd rd()
void wt(int x){
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
wt(x / 10);
putchar(x % 10 + '0');
return;
}
void wt(char x){
putchar(x);
}
void wt(int x, char k){
wt(x),putchar(k);
}
namespace Star_F{
const int N = 4000010;
struct Tree{
int l, r, w, mx;
} tr[N << 2];
int a[N], n, m;
void pushup(int u){
tr[u].w = tr[u << 1].w + tr[u << 1 | 1].w;
tr[u].mx = max(tr[u << 1].mx, tr[u << 1 | 1].mx);
}
void build(int u,int l,int r){
tr[u].l = l, tr[u].r = r;
if(l==r){
tr[u].w = tr[u].mx = a[l];
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void update(int u,int l,int r){
if(tr[u].l==tr[u].r){
tr[u].w = sqrt(tr[u].w), tr[u].mx = tr[u].w;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if(l<=mid&&tr[u<<1].mx>1)
update(u << 1, l, r);
if(r>mid&&tr[u<<1|1].mx>1)
update(u << 1 | 1, l, r);
pushup(u);
}
int query(int u,int l,int r){
//DEBUG(u), DEBUG(l), DEBUG(r);
if(tr[u].l>=l&&tr[u].r<=r){
return tr[u].w;
}
int mid = tr[u].l+tr[u].r >> 1, res = 0;
if(l<=mid)
res += query(u << 1, l, r);
if(r>mid)
res += query(u << 1 | 1, l, r);
return res;
}
void Main(){
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
build(1, 1, n);
cin >> m;
for (int i = 1; i <= m;i++){
int opt, x, y;
cin >> opt >> x >> y;
if(x>y)
swap(x, y);
if(opt==1) {
cout << query(1, x, y) << endl;
}
else{
update(1, x, y);
}
}
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ClockA;
int T=1;
// T=rd;
while(T--) Star_F::Main();
// ClockB;
return 0;
}
/*
* ▀▀▀██████▄▄▄ _______________
* ▄▄▄▄▄ █████████▄ / \
* ▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Code has no BUG! |
* ▀▀█████▄▄ ▀██████▄██ | _________________/
* ▀▄▄▄▄▄ ▀▀█▄▀█════█▀ |/
* ▀▀▀▄ ▀▀███ ▀ ▄▄
* ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌ ______________________________
* ██▀▄▄▄██▀▄███▀ ▀▀████ ▄██ █ \\
* ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███ ▌▄▄▀▀▀▀█_____________________________ //
* ▌ ▐▀████▐███▒▒▒▒▒▐██▌
* ▀▄▄▄▄▀ ▀▀████▒▒▒▒▄██▀
* ▀▀█████████▀
* ▄▄██▀██████▀█
* ▄██▀ ▀▀▀ █
* ▄█ ▐▌
* ▄▄▄▄█▌ ▀█▄▄▄▄▀▀▄
* ▌ ▐ ▀▀▄▄▄▀
* ▀▀▄▄▀ ██
* \ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
* \- ▌ Name: Star_F ▀ ▀
* - ▌ (o) ▀
* /- ▌ Go Go Go ! ▀ ▀
* / ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
*/
P4513 小白逛公园
纯线段树,考虑每个区间,维护当前区间的最大子段和,最大前缀和,最大后缀和。
pushup
合并时分别考虑三种情况(左子树的最大子段和,右子树的最大子段和,左子树的最大后缀和
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define ROF(i, a, b) for (int i = (a); i >= (b); --i)
#define DEBUG(x) cerr << #x << " = " << x << endl
#define ll long long
typedef pair <int, int> PII;
typedef unsigned int uint;
typedef unsigned long long ull;
#define i128 __int128
#define fi first
#define se second
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
#define ClockA clock_t start, end; start = clock()
#define ClockB end = clock(); cerr << "time = " << double(end - start) / CLOCKS_PER_SEC << "s" << endl;
//#define int long long
inline int rd(){
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
#define rd rd()
void wt(int x){
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
wt(x / 10);
putchar(x % 10 + '0');
return;
}
void wt(char x){
putchar(x);
}
void wt(int x, char k){
wt(x),putchar(k);
}
namespace Star_F{
const int N = 500010;
int n, m;
int w[N];
struct Node{
int l, r;
int sum, lmax, rmax, tmax;
}tr[N * 4];
void pushup(Node &u, Node &l, Node &r){
u.sum = l.sum + r.sum;
u.lmax = max(l.lmax, l.sum + r.lmax);
u.rmax = max(r.rmax, r.sum + l.rmax);
u.tmax = max(max(l.tmax, r.tmax), l.rmax + r.lmax);
}
void pushup(int u){
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void build(int u, int l, int r){
if (l == r) tr[u] = {l, r, w[r], w[r], w[r], w[r]};
else{
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int x, int v){
if (tr[u].l == x && tr[u].r == x) tr[u] = {x, x, v, v, v, v};
else{
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) modify(u << 1, x, v);
else modify(u << 1 | 1, x, v);
pushup(u);
}
}
Node query(int u, int l, int r){
if (tr[u].l >= l && tr[u].r <= r) return tr[u];
else{
int mid = tr[u].l + tr[u].r >> 1;
if (r <= mid) return query(u << 1, l, r);
else if (l > mid) return query(u << 1 | 1, l, r);
else{
auto left = query(u << 1, l, r);
auto right = query(u << 1 | 1, l, r);
Node res;
pushup(res, left, right);
return res;
}
}
}
void Main(){
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> w[i];
build(1, 1, n);
int k, x, y;
while (m--){
cin >> k >> x >> y;
if (k == 1){
if (x > y) swap(x, y);
printf("%d\n", query(1, x, y).tmax);
}
else modify(1, x, y);
}
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ClockA;
int T=1;
// T=rd;
while(T--) Star_F::Main();
// ClockB;
return 0;
}
/*
* ▀▀▀██████▄▄▄ _______________
* ▄▄▄▄▄ █████████▄ / \
* ▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Code has no BUG! |
* ▀▀█████▄▄ ▀██████▄██ | _________________/
* ▀▄▄▄▄▄ ▀▀█▄▀█════█▀ |/
* ▀▀▀▄ ▀▀███ ▀ ▄▄
* ▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌ ______________________________
* ██▀▄▄▄██▀▄███▀ ▀▀████ ▄██ █ \\
* ▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███ ▌▄▄▀▀▀▀█_____________________________ //
* ▌ ▐▀████▐███▒▒▒▒▒▐██▌
* ▀▄▄▄▄▀ ▀▀████▒▒▒▒▄██▀
* ▀▀█████████▀
* ▄▄██▀██████▀█
* ▄██▀ ▀▀▀ █
* ▄█ ▐▌
* ▄▄▄▄█▌ ▀█▄▄▄▄▀▀▄
* ▌ ▐ ▀▀▄▄▄▀
* ▀▀▄▄▀ ██
* \ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
* \- ▌ Name: Star_F ▀ ▀
* - ▌ (o) ▀
* /- ▌ Go Go Go ! ▀ ▀
* / ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀
*/
P1486 [NOI2004] 郁闷的出纳员
我会 Splay
!
其实就是值域线段树,把每个员工的工资当作节点编号,节点的值当作出现次数,然后区间修改即可。
由于是全体工资加 add
即可。
因为编号都是大于
#include<bits/stdc++.h>
using namespace std;
const int M = 200005;
const int N = 500005;
struct Tree{
int l,r;
int sum,rem;
}t[N<<2];
int n,lim,D,now,ans;
void pushdown(int p){
if(t[p].rem){
t[p << 1].sum = t[p << 1 | 1].sum = 0;
t[p << 1].rem = t[p << 1 | 1].rem = 1;
t[p].rem = 0;
}
}
void pushup(int p) {
t[p].sum = t[p << 1].sum + t[p << 1 | 1].sum;
}
void build(int p,int l,int r){
t[p].l = l, t[p].r = r;
if(l==r){t[p].sum=0;
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
pushup(p);
}
void change(int p,int x,int val){
if(t[p].l==t[p].r){
t[p].sum += val;
return;
}
pushdown(p);
int mid = (t[p].l + t[p].r) >> 1;
if(x<=mid)
change(p << 1, x, val);
else
change(p << 1 | 1, x, val);
pushup(p);
}
int query(int p,int k){
if(t[p].l==t[p].r)
return t[p].l;
pushdown(p);
if(t[p<<1].sum>=k)
return query(p << 1, k);
else
return query(p << 1 | 1, k - t[p << 1].sum);
}
void upd(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
if(t[p].sum)
now -= t[p].sum, ans += t[p].sum;
t[p].sum = 0, t[p].rem = 1;
return;
}
pushdown(p);
int mid = (t[p].l + t[p].r) >> 1;
if(l<=mid)
upd(p << 1, l, r);
if(r>mid)
upd(p << 1 | 1, l, r);
pushup(p);
}
int main(){
cin >> n >> lim;
char op;
build(1,1,N);
for (int i = 1; i <= n; ++i){
int k;
cin >> op >> k;
if(op=='I'){
if(k>=lim)
change(1, k - D + M, 1), now++;
}
else if(op=='A')
D += k;
else if(op=='S')
D -= k, upd(1, 1, lim - D - 1 + M);
else if(op=='F'){
if(k>now) puts("-1");
else cout << query(1, now - k + 1) + D - M << endl;
}
}
cout << ans << endl;
return 0;
}
P2824 [HEOI2016/TJOI2016] 排序
很神秘的一道题,调了好久。
考虑对于每个区间排序是很复杂的事情,但如果一个区间只有
我们可以二分答案,假设当前答案为 l=mid+1
,否则 r=mid-1
。
于是便可得出,线段树维护 区间和,tag(被覆盖成 tag )就可以了
复杂度
#include <bits/stdc++.h>
using namespace std;
const int N = 400005;
struct Tree{
int l, r;
int w, tag;
} tr[N << 2];
int a[N];
void pushup(int u){
tr[u].w = tr[u << 1].w + tr[u << 1 | 1].w;
}
void build(int u, int l, int r) {
tr[u].l=l,tr[u].r=r,tr[u].tag = -1;
if (l == r) {
tr[u].w = a[l];
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void pushdown(int u, int l, int r, int mid) {
if (tr[u].tag == -1) return;
tr[u << 1].tag = tr[u << 1 | 1].tag = tr[u].tag;
tr[u << 1].w = tr[u].tag * (mid - l + 1);
tr[u << 1 | 1].w = tr[u].tag * (r - mid);
tr[u].tag = -1;
}
void cov(int u, int l,int r,int v) {
if (l <= tr[u].l && tr[u].r <= r) {
tr[u].tag = v;
tr[u].w = v * (tr[u].r - tr[u].l + 1);
return;
}
int mid = tr[u].l+tr[u].r >> 1;
pushdown(u, tr[u].l, tr[u].r, mid);
if (l <= mid)
cov(u << 1, l, r, v);
if (r > mid)
cov(u << 1 | 1,l, r, v);
pushup(u);
}
int ask(int u, int l, int r) {
//cout<<u<<" "<<l<<" "<<r<<endl;
if (l<=tr[u].l && tr[u].r<=r)
return tr[u].w;
int mid = tr[u].l+tr[u].r>> 1, ans = 0;
pushdown(u, tr[u].l, tr[u].r, mid);
if (l <= mid)
ans += ask(u << 1, l, r);
if (r > mid)
ans += ask(u << 1 | 1,l, r);
return ans;
}
int b[N], n;
int opt[N], l[N], r[N], m, q;
bool solve(int x) {
for (int i = 1; i <= n; i++) {
if (b[i] >= x) a[i] = 1;
else a[i] = 0;
}
build(1, 1, n);
for (int i = 1; i <= m; i++) {
if (opt[i] == 1) {
int num = ask(1,l[i], r[i]);
cov(1, l[i], l[i] + num - 1, 1);
cov(1, l[i] + num, r[i], 0);
} else {
int num = ask(1, l[i], r[i]);
cov(1, r[i] - num + 1, r[i], 1);
cov(1, l[i], r[i] - num, 0);
}
}
return ask(1, q, q);
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> b[i];
for (int i = 1; i <= m; i++) {
cin >> opt[i] >> l[i] >> r[i];
}
cin >> q;
int l = 1, r = n, ans = 0;
while (l <= r) {
int mid = l + r >> 1;
if (solve(mid))
ans = mid, l = mid + 1;
else
r = mid - 1;
}
cout << ans+1 << endl;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库