高级非递归线段树模板

就决定是你了, 模板确定,(╯‵□′)╯︵┻━┻其他不玩了

//HDU1542矩形面积并

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>


using namespace std;


const int N = 111;


int n;
vector<double> y;


struct node
{
double s;
int c;
int l, r;
void chu(double ss, int cc, int ll, int rr)
{
s =  ss;
c = cc;
l = ll, r = rr;
}
double len()
{
return y[r] - y[l - 1];
}
} g[N << 4];
int M;


void init(int n)
{
for (M = 1; M < n + 2; M <<= 1);
g[M].chu(0, 0, 1, 1);
for (int i = 1; i <= n; i++)
g[i + M].chu(0, 0, i, i);
for (int i = n + 1; i < M; i++)
g[i + M].chu(0, 0, n, n);
for (int i = M - 1; i > 0; i--)
g[i].chu(0, 0, g[i << 1].l, g[i << 1 | 1].r);
}


struct line
{
double x, yl, yr;
int d;
line() {}
line(double x, double yl, double yr, int dd): x(x), yl(yl), yr(yr), d(dd) {}
bool operator < (const line &cc)const
{
return x < cc.x || (x == cc.x && d > cc.d);
}
};


vector<line>L;


void one(int x)
{
if (x >= M)
{
g[x].s = g[x].c ? g[x].len() : 0;
return;
}
g[x].s = g[x].c ? g[x].len() : g[x << 1].s + g[x << 1 | 1].s;
}


void up(int x)
{
for (; x; x >>= 1)
one(x);
}


void add(int l, int r, int d)
{
if (l > r)return;
l += M - 1, r += M + 1;
for (int s = l, t = r; s ^ t ^ 1; s >>= 1, t >>= 1)
{
if (~s & 1)
{
g[s ^ 1].c += d;
one(s ^ 1);
}
if (t & 1)
{
g[t ^ 1].c += d;
one(t ^ 1);
}
}
up(l);
up(r);
}


double sol()
{
y.clear();
L.clear();
for (int i = 0; i < n; i++)
{
double lx, ly, rx, ry;
scanf("%lf %lf %lf %lf", &lx, &ly, &rx, &ry);
L.push_back(line(lx, ly, ry, 1));
L.push_back(line(rx, ly, ry, -1));
y.push_back(ly);
y.push_back(ry);
}
sort(y.begin(), y.end());
y.erase(unique(y.begin(), y.end()), y.end());
init(y.size());
sort(L.begin(), L.end());
n = L.size() - 1;
double ans = 0;
for (int i = 0; i < n; i++)
{
int l = upper_bound(y.begin(), y.end(), L[i].yl + 1e-8) - y.begin();
int r = upper_bound(y.begin(), y.end(), L[i].yr + 1e-8) - y.begin() - 1;
add(l, r, L[i].d);
ans += g[1].s * (L[i + 1].x - L[i].x);
}
return ans;
}


int main()
{
int ca = 1;
while (cin >> n && n)
{
printf("Test case #%d\nTotal explored area: %.2f\n\n", ca++, sol());
}
return 0;
}
//HDU1828矩形周长并
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <iostream>


using namespace std;


const int Z = 10000 + 1;


struct line
{
int x, yl, yr , o;
line() {}
line(int x, int yl, int yr, int o): x(x), yl(yl), yr(yr), o(o) {}


bool operator < (const line& c)const
{
return x < c.x;
}
};


struct node
{
int l, r, c, num, S;
bool lb, rb;
void mem(int L, int R)
{
l = L, r = R;
c = num = S = 0;
lb = rb = false;
}
void cb(node a, node b)
{
l = a.l, r = b.r;
lb = a.lb, rb = b.rb;
num = a.num + b.num - 2 * (a.rb && b.lb);
S = a.S + b.S;
}
};


int m;
vector<line>L;
node g[Z << 3];


void get(int x)
{
if (g[x].c)
{
g[x].S = g[x].r - g[x].l;
g[x].num = 2;
g[x].lb = g[x].rb = true;
}
else if (g[x].r - g[x].l == 1)
{
g[x].S = 0;
g[x].num = 0;
g[x].lb = g[x].rb = false;
}
else
{
g[x].cb(g[x << 1], g[x << 1 | 1]);
}
}


void up(int x)
{
for (x >>= 1; x; x >>= 1)
get(x);
}


void add(int l, int r, int d)
{
l += m - 1;
r += m + 1;
for (int s = l, t = r; s ^ t ^ 1; s >>= 1, t >>= 1)
{
if (~s & 1)
{
g[s ^ 1].c += d;
get(s ^ 1);
}
if (t & 1)
{
g[t ^ 1].c += d;
get(t ^ 1);
}
}
up(l);
up(r);
}


void chu()
{
for (int i = m; i < m + m; i++)
{
g[i].mem(i - m - 1, i - m);
}
for (int i = m - 1; i > 0; i--)
{
g[i].cb(g[i<<1],g[i<<1|1]);
}
}


int main()
{
int n;
for (m = 1; m < Z * 2; m <<= 1);
while (cin >> n)
{
chu();
L.clear();
for (int i = 0; i < n; i++)
{
   int a,b,c,d;
scanf("%d%d%d%d", &a, &b, &c, &d);
int xl = min(a, c), xr = max(a, c);
int yl = min(b, d), yr = max(b, d);
L.push_back(line(xl, yl, yr, 1));
L.push_back(line(xr, yl, yr, -1));
}
sort(L.begin(), L.end());
int ans = 0;
int lat = 0;
for (int i = 0; i < L.size(); i++)
{
if (i)ans += g[1].num * (L[i].x - L[i - 1].x);
add(L[i].yl + Z, L[i].yr + Z - 1, L[i].o);
ans += abs(lat - g[1].S);
lat = g[1].S;
}
cout<<ans<<endl;
}
return 0;
}
//POJ2155二维线段树
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <iostream>


using namespace std;


const int W = 1000;


int m;


struct tree
{
int d[W << 2];
void o()
{
for (int i = 1; i < m + m; i++)d[i] = 0;
}
void Xor(int l, int r)
{
l += m - 1, r += m + 1;
for (int s = l, t = r; s ^ t ^ 1; s >>= 1, t >>= 1)
{
if (~s & 1)d[s ^ 1] ^= 1;
if (t & 1)d[t ^ 1] ^= 1;
}
}


} g[W << 2];


void chu()
{
for (int i = 1; i < m + m; i++)
g[i].o();
}




void Xor(int lx, int ly, int rx, int ry)
{
lx += m - 1, rx += m + 1;
for (int s = lx, t = rx; s ^ t ^ 1; s >>= 1, t >>= 1)
{
if (~s & 1)g[s ^ 1].Xor(ly, ry);
if (t & 1)g[t ^ 1].Xor(ly, ry);
}
}


int Q(int x, int y)
{
int ans = 0;
for (int xx = x + m; xx; xx >>= 1)
{
for (int yy = y + m; yy; yy >>= 1)
{
ans ^= g[xx].d[yy];
}
}
return ans;
}


int main()
{
int T;
cin >> T;
int fl = 0;
while (T--)
{
if (fl)
{
printf("\n");
}
fl = 1;
int N, M;
cin >> N >> M;
for (m =  1; m < N + 2; m <<= 1);
chu();
while (M--)
{
char o[4];
scanf("%s", o);
if (*o == 'Q')
{
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", Q(x, y));
}
else
{
int lx, ly, rx, ry;
scanf("%d%d%d%d", &lx, &ly, &rx, &ry);
Xor(lx, ly, rx, ry);
}
}
}
return 0;
}
//POJ3667区间合并
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>


using namespace std;


const int N = 50000;


int M, T;
int L[N << 2];


struct node
{
int l, r;
int ln, rn, mn;
int is;
node() {}
node(int l, int r, int ln, int rn, int mn, int is): l(l), r(r), ln(ln), rn(rn), mn(mn), is(is) {}
node operator + (const node& c)const
{
return node(l, c.r, ln == r - l + 1 ? ln + c.ln : ln, c.rn == c.r - c.l + 1 ? rn + c.rn : c.rn, max(max(mn, c.mn), rn + c.ln), 0);
}
} g[N << 2];


void chu(int n)
{
memset(L, 0, sizeof(L));
int i;
for (i = 1 + M; i <= M + n; i++)
L[i] = 1, g[i] = node(i - M, i - M, 1, 1, 1, 0);
for (; i < M + M; i++)
g[i] = node(i - M, i - M, 0, 0, 0, 0);
g[M] = node(0, 0, 0, 0, 0, 0);
for (i = M - 1; i > 0; i--)
{
L[i] = L[i << 1] + L[i << 1 | 1];
g[i] = g[i << 1] + g[i << 1 | 1];
}
}


void one(int f)
{
int l = f << 1, r = l ^ 1;
if (g[f].is)
{
g[l].is = g[r].is = g[f].is;
g[l].ln = g[l].rn = g[l].mn = g[f].is - 1 ? 0 : L[l];
g[r].ln = g[r].rn = g[r].mn = g[f].is - 1 ? 0 : L[r];
g[f].is = 0;
}
}


void dn(int x)
{
for (int i = T - 1; i > 0; i--)
one(x >> i);
}


int find(int x, int D)
{
int l = x << 1, r = l ^ 1;
one(x);
if (g[l].mn >= D)return find(l, D);
if (g[r].ln + g[l].rn >= D)return g[l].r - g[l].rn + 1;
return find(r, D);
}




void up(int x)
{
for (x >>= 1; x; x >>= 1)
if (!g[x].is)g[x] = g[x << 1] + g[x << 1 | 1];
}


void add(int l, int r, int o)
{
l += M - 1, r += M + 1;
dn(l), dn(r);
int s = l, t = r;
for (; l ^ r ^ 1; l >>= 1, r >>= 1)
{
if (~l & 1)
{
g[l ^ 1].ln = g[l ^ 1].rn = g[l ^ 1].mn = o ? 0 : L[l ^ 1];
g[l ^ 1].is = 1 + o;
}
if (r & 1)
{
g[r ^ 1].ln = g[r ^ 1].rn = g[r ^ 1].mn = o ? 0 : L[r ^ 1];
g[r ^ 1].is = 1 + o;
}
}
up(s), up(t);
}


int main()
{
int n, m;
while (cin >> n >> m)
{
for (M = T = 1; M <= n + 1; M <<= 1, T++);
chu(n);
while (m--)
{
int o, d, l;
scanf("%d", &o);
if (o == 1)
{
scanf("%d", &d);
if (g[1].mn < d)
{
printf("0\n");
continue;
}
l = find(1, d);
printf("%d\n", l);
add(l, l + d - 1, 1);
}
else
{
scanf("%d %d", &l, &d);
add(l, l + d - 1, 0);
}
}
}
return 0;
}
//HDU4267多颗线段树(不连续区间)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <iostream>


using namespace std;


typedef long long ll;


const int N = 50000;


int m, t;
int n;


int d[55][65536 * 2];


int a[N + 1];


void dn(int*b, int x)
{
for (int i = t - 1; i > 0; i--)
{
int f = x >> i;
b[f << 1] += b[f];
b[f << 1 | 1] += b[f];
b[f] = 0;
}
}


void add(int*b, int l, int r, int v)
{
l += m - 1, r += m + 1;
for (int s = l, t = r; s ^ t ^ 1; s >>= 1, t >>= 1)
{
if (~s & 1)b[s ^ 1] += v;
if (t & 1)b[t ^ 1] += v;
}
}


int main()
{
while (cin >> n)
{
for (m = t = 1; m < n + 4; m <<= 1, t++);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
memset(d, 0, sizeof(d));
int q;
cin >> q;
while (q--)
{
int o;
int id;
scanf("%d", &o);
if (o - 1)
{
scanf("%d", &id);
ll ans = a[id];
for (int i = 1; i <= 10; i++)
{
int j = id % i + i * (i - 1) / 2;
dn(d[j], id / i + 1 + m);
ans += d[j][id / i + 1 + m];
}
printf("%I64d\n", ans);
}
else
{
int a, b, c, k;
scanf("%d%d%d%d", &a, &b, &k, &c);
int j = a % k + k * (k - 1) / 2;
add(d[j], a / k + 1, a / k + 1 + (b - a) / k, c);
}
}
}
return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值