HDOJ:6356-Glad You Came(线段树剪枝)

时间:2023-03-08 17:34:31
HDOJ:6356-Glad You Came(线段树剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356

解题心得:

  • 现在深深的知道了算法复杂度的重要了,这个题算复杂度的时候还要把一些常数也算出来,不然常数太大也容易凉凉阿。这个题的m的数量级比n的还要大一位,如果用离线对询问排序直接就TLE了。
  • 其实这个题就是一个区间更新的线段树,只不过记录一下最小值,如果最小值大于将要更新的值就直接跳出,在线段树上剪枝。然而很迷的是在把m的内存开小了,开成n了居然不RE而是TLE,坑死了。
//
// ┏┛ ┻━━━━━┛ ┻┓
// ┃       ┃
// ┃   ━   ┃
// ┃ ┳┛  ┗┳ ┃
// ┃       ┃
// ┃   ┻   ┃
// ┃       ┃
// ┗━┓   ┏━━━┛
// ┃   ┃ 神兽保佑
// ┃   ┃ 代码无BUG!
// ┃   ┗━━━━━━━━━┓
// ┃        ┣┓
// ┃     ┏┛
// ┗━┓ ┓ ┏━━━┳ ┓ ┏━┛
// ┃ ┫ ┫ ┃ ┫ ┫
// ┗━┻━┛ ┗━┻━┛
#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5;
const int maxm = 2e7+;
typedef long long ll;
long long f[maxm];
int n,m;
unsigned int x,y,z,w;
struct NODE {
ll Min,va;
}node[maxn]; void pre() {
for(int i=;i<=*m;i++) {
x = x ^ (x << );
x = x ^ (x >> );
x = x ^ (x << );
x = x ^ (x >> );
w = x ^ (y ^ z);
x = y;
y = z;
z = w;
f[i] = z;
}
} void init() {
scanf("%d%d%u%u%u",&n,&m,&x,&y,&z);
pre();
} void pushdown(int root) {
if(node[root].va == )
return ;
int chl = root<<;
int chr = root<<|;
node[chl].va = max(node[chl].va, node[root].va);
node[chr].va = max(node[chr].va, node[root].va);
node[chl].Min = max(node[chl].Min, node[root].va);
node[chr].Min = max(node[chr].Min, node[root].va);
node[root].va = ;
} void updata(int root) {
int chl = root<<;
int chr = root<<|;
node[root].Min = min(node[chl].Min, node[chr].Min);
} void change(int root,int ql, int qr, int l, int r,ll va) {
if(va <= node[root].Min || r < ql || l > qr)
return ;
if(ql <= l && qr >= r) {
node[root].va = max(node[root].va,va);
node[root].Min = max(node[root].Min,va);
return ;
}
pushdown(root);
int mid = (l + r) >> ;
int chl = root<<;
int chr = root<<|; change(chl, ql, qr, l, mid, va);
change(chr, ql, qr, mid+, r, va);
updata(root);
} ll ans = ; void get_ans(int root,int l,int r) {
if(l == r) {
ans ^= 1ll * node[root].Min * l;
return ;
}
pushdown(root);
int mid = (l + r) >> ;
int chl = root<<;
int chr = root<<|;
get_ans(chl, l, mid);
get_ans(chr, mid+, r);
} int main() {
int t;
scanf("%d",&t);
while(t--) {
memset(node, , sizeof(node));
init();
for(int i=;i<=m;i++) {
ll l = min(f[*i-]%n+, f[*i-]%n+);
ll r = max(f[*i-]%n+, f[*i-]%n+);
ll v = f[*i]%(<<);
change(, l, r, , n, v);
}
ans = ;
get_ans(, , n);
printf("%lld\n",ans);
}
return ;
}