HDOJ:6356-Glad You Came(线段树剪枝)
Posted goldenfingers
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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+100; 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=1;i<=3*m;i++) { x = x ^ (x << 11); x = x ^ (x >> 4); x = x ^ (x << 5); x = x ^ (x >> 14); 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 == 0) return ; int chl = root<<1; int chr = root<<1|1; 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 = 0; } void updata(int root) { int chl = root<<1; int chr = root<<1|1; 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) >> 1; int chl = root<<1; int chr = root<<1|1; change(chl, ql, qr, l, mid, va); change(chr, ql, qr, mid+1, r, va); updata(root); } ll ans = 0; 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) >> 1; int chl = root<<1; int chr = root<<1|1; get_ans(chl, l, mid); get_ans(chr, mid+1, r); } int main() { int t; scanf("%d",&t); while(t--) { memset(node, 0, sizeof(node)); init(); for(int i=1;i<=m;i++) { ll l = min(f[3*i-2]%n+1, f[3*i-1]%n+1); ll r = max(f[3*i-2]%n+1, f[3*i-1]%n+1); ll v = f[3*i]%(1<<30); change(1, l, r, 1, n, v); } ans = 0; get_ans(1, 1, n); printf("%lld ",ans); } return 0; }
以上是关于HDOJ:6356-Glad You Came(线段树剪枝)的主要内容,如果未能解决你的问题,请参考以下文章
HDU6356:Glad You Came ST表的巧妙利用
HDU 6356 Glad You Came 2018 Multi-University Training Contest 5 (线段树)
杭电2018多校第五场(2018 Multi-University Training Contest 5) 1007.Glad You Came (HDU6356)-区间更新-线段树+剪枝