[FJOI2015]火星商店问题
Posted lordxx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[FJOI2015]火星商店问题相关的知识,希望对你有一定的参考价值。
线段树分治。以时间轴建立线段树,每一个线段树节点,存放[L,R]时间内,有影响的操作1,建立可持久化trie树,trie树以商店位置为root,就可以支持商店的区间查询,然后将操作0,按照商店位置排序,进行线段树分治,每次到一个节点,先把操作0插入trie树,然后把所有当前时间内存的有影响的操作1全部拿出来,进行查询即可。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<‘0‘ || ch>‘9‘) { if (ch == ‘-‘)f = -1; ch = getchar(); }
while (ch >= ‘0‘ && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
struct trie {
int ch[N * 22][2]; int root[N];
int sum[N * 22];
int tot;
void clear()
{
tot = 0;
}
void insert(int &o, int pre, int x,int pos)
{
o = ++tot;
sum[o] = sum[pre] + 1;
if (pos == -1)return;
int f = (x >> pos & 1);
ch[o][f ^ 1] = ch[pre][f ^ 1];
insert(ch[o][f], ch[pre][f], x, pos - 1);
}
int query(int l, int r, int x, int pos)
{
if (pos == -1)return 0;
int f = (x >> pos & 1);
if (sum[ch[r][f ^ 1]] - sum[ch[l][f ^ 1]])
{
return query(ch[l][f ^ 1], ch[r][f ^ 1], x, pos - 1) + (1 << pos);
}
else return query(ch[l][f], ch[r][f], x, pos - 1);
}
}T;
int n, m;
int node_cnt, day;
struct node {
int st, ed, l, r, x, id;
}nd[N];
struct shop {
int d, v, p;
bool operator<(const shop p)const {
return d < p.d;
}
}sp[N];
int ans[N];
struct Tree {
vector<int> tr[N << 2];
void update(int l, int r, int root, int L,int R,int id)
{
if (L > R)return;
if (L <= l && r <= R)
{
tr[root].push_back(id);
return;
}
int mid = (l + r) >> 1;
if (L <= mid)update(lson, L, R, id);
if (R > mid)update(rson,L, R, id);
}
void cal(int L, int R, int root)
{
T.clear();
int temp = 1;
vector<int>vec;
upd(i, L, R)
{
vec.push_back(sp[i].d);
T.insert(T.root[temp], T.root[temp - 1], sp[i].v, 20);
temp++;
}
for (auto k : tr[root])
{
int lf = upper_bound(vec.begin(), vec.end(), nd[k].l - 1) - vec.begin();
int rt = upper_bound(vec.begin(), vec.end(), nd[k].r) - vec.begin();
ans[nd[k].id] = max(ans[nd[k].id], T.query(T.root[lf], T.root[rt], nd[k].x, 20));
}
}
void div(int l, int r,int root, int L, int R)
{
if (L > R)return;
cal(L, R, root);
if (l == r)return;
int mid = (l + r) >> 1;
vector<shop>t1, t2;
upd(i, L, R)
{
if (sp[i].p <= mid)t1.push_back(sp[i]);
else t2.push_back(sp[i]);
}
up(i, 0, t1.size())sp[L + i] = t1[i];
up(i, 0, t2.size())sp[L + t1.size() + i] = t2[i];
div(lson, L, L + t1.size() - 1);
div(rson, L + t1.size(), R);
}
}seg;
int main()
{
n = read(), m = read();
int u;
upd(i, 1, n)
{
u = read();
T.insert(T.root[i], T.root[i - 1], u, 20);
}
int op, l, r, x, d;
while (m--) {
op = read();
if (op)
{
l = read(), r = read(), x = read(), d = read();
++node_cnt;
nd[node_cnt] = node{ max(day - d + 1,1),day,l,r,x,node_cnt };
ans[node_cnt] = T.query(T.root[l - 1], T.root[r], x, 20);
}
else {
day++;
l = read(), r = read();
sp[day] = shop{ l,r ,day };
}
}
sort(sp + 1, sp + day + 1);
upd(i, 1, node_cnt)
seg.update(1, day, 1, nd[i].st, nd[i].ed, nd[i].id);
seg.div(1, day, 1, 1, day);
upd(i, 1, node_cnt)
{
printf("%d
", ans[i]);
}
return 0;
}
以上是关于[FJOI2015]火星商店问题的主要内容,如果未能解决你的问题,请参考以下文章