hdu 5828 Rikka with Sequence 【加强版已过】
2016-08-12 16:42
429 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828
转载链接:http://blog.csdn.net/xtttgo/article/details/52184771
(数据加强后代码AC)
题意:
线段树基本操作题
给你一个区间 有3个指令
1 l r x:【l,r】+x;
2 l r:【l,r】中的每个元素都得开根号
3 l r : 【l,r】中的值的和
个人感想:
马丹,我今天做了一个上午,才告诉我数据加强了,大部分题解都是T的,然后我也不会了….我只能说说我的想法吧,我现在也没找到一个blog能过的….我这种蒟蒻看不懂大牛的题解…
这题如果有做过区间开根的朋友应该第一想法就是 对于根号的单点更新,直到整段区间是1或者相同的时候合并成单点,然后相当于对区间操作时转化成单点操作.
就算会做,但现在也卡不过了,数据加强了….当时比赛的时候,我也有这个想法,我是感觉会T我都不敢写,然后大部分题解都说合并就可以过了..数据加强后,真的一个都过不了了… 标程也不能过,简直什么鬼..
附加:
现在22:14分,马丹我今天敲了一天了这道题,我终于AC掉了,参考了一下大牛的文章,然后再在自己的基础上改的,转载的大牛文章说有这样的数据 2 3 2 3 2 3..,然后不断的+d,然后再开根,无限的这样子就会必然会T.
然后看了一下大牛文章,当时大牛没修改它原本文章的表达,反正有点奇怪,之后我悟道了什么意思.
这挺神奇的思想,我是没考虑过..
假设某一段区间的最大值x,和最小值y.
如果极差>1,那么这个极差经过很少的次数开根号, 其中的极差也会变得越来越小,
用公式来表达 假设当前这段区间要+d,然后再开根号.
必然有这样的式子
所以我们很容易就求到这个段区间的值.
这里有个小极巧
所以 极差<=1的时候可以特殊处理
假设 这段区间极差==1,那么我们很容易求到这段区间的最大最小值,
因为我们知道上一次的 Sum
所以我们可以这样, 最大值的个数=Sum-(r-l+1)*最小值.然后就顺便求出最大值,然后如果当前区间要开根号的话,直接就可以求出来了..
好累…回宿舍..
T代码:
AC代码:
转载链接:http://blog.csdn.net/xtttgo/article/details/52184771
(数据加强后代码AC)
题意:
线段树基本操作题
给你一个区间 有3个指令
1 l r x:【l,r】+x;
2 l r:【l,r】中的每个元素都得开根号
3 l r : 【l,r】中的值的和
个人感想:
马丹,我今天做了一个上午,才告诉我数据加强了,大部分题解都是T的,然后我也不会了….我只能说说我的想法吧,我现在也没找到一个blog能过的….我这种蒟蒻看不懂大牛的题解…
这题如果有做过区间开根的朋友应该第一想法就是 对于根号的单点更新,直到整段区间是1或者相同的时候合并成单点,然后相当于对区间操作时转化成单点操作.
就算会做,但现在也卡不过了,数据加强了….当时比赛的时候,我也有这个想法,我是感觉会T我都不敢写,然后大部分题解都说合并就可以过了..数据加强后,真的一个都过不了了… 标程也不能过,简直什么鬼..
附加:
现在22:14分,马丹我今天敲了一天了这道题,我终于AC掉了,参考了一下大牛的文章,然后再在自己的基础上改的,转载的大牛文章说有这样的数据 2 3 2 3 2 3..,然后不断的+d,然后再开根,无限的这样子就会必然会T.
然后看了一下大牛文章,当时大牛没修改它原本文章的表达,反正有点奇怪,之后我悟道了什么意思.
这挺神奇的思想,我是没考虑过..
假设某一段区间的最大值x,和最小值y.
如果极差>1,那么这个极差经过很少的次数开根号, 其中的极差也会变得越来越小,
用公式来表达 假设当前这段区间要+d,然后再开根号.
必然有这样的式子
\( \lfloor \sqrt{x+d} \rfloor - \lfloor \sqrt{y+d} \rfloor <= \lfloor \sqrt{x} \rfloor - \lfloor \sqrt{y} \rfloor \)
就是他的极差会越来越小,反正开一次根号都变得越来越小.所以我们很容易就求到这个段区间的值.
这里有个小极巧
所以 极差<=1的时候可以特殊处理
假设 这段区间极差==1,那么我们很容易求到这段区间的最大最小值,
因为我们知道上一次的 Sum
所以我们可以这样, 最大值的个数=Sum-(r-l+1)*最小值.然后就顺便求出最大值,然后如果当前区间要开根号的话,直接就可以求出来了..
好累…回宿舍..
T代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define lson 2*k #define rson 2*k+1 typedef long long ll; const ll INF = 0x3f3f3f3f; const ll maxn = 1e5 + 10; ll Scan()//读入整数外挂. { ll res = 0, ch, flag = 0; if((ch = getchar()) == '-') //判断正负 flag = 1; else if(ch >= '0' && ch <= '9') //得到完整的数 res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9' ) res = res * 10 + ch - '0'; return flag ? -res : res; } void Out(ll a) //输出外挂 { if(a > 9) Out(a / 10); putchar(a % 10 + '0'); //prllf("\n"); } /*1.加上一个值 2.开根号 3.计算总值 */ int T; int n, m; int op; int l, r; ll x; ll A[maxn]; class Node { public: int l; int r; ll sum; ll lazy; ll flag;//用flag来判断是否有整段的值都是一样的. }; Node node[4 * maxn]; void pushup(int k) { if(node[lson].flag==node[rson].flag&&node[lson].flag) { node[k].flag=node[lson].flag; } else node[k].flag=0; node[k].sum=node[lson].sum+node[rson].sum; } void pushdown(int k) { if(node[k].flag) { node[lson].flag=node[k].flag; node[rson].flag=node[k].flag; node[lson].sum=(node[lson].r-node[lson].l+1)*node[k].flag; node[rson].sum=(node[rson].r-node[rson].l+1)*node[k].flag; node[k].lazy=0; } if(node[k].lazy) { node[lson].sum+=(node[lson].r-node[lson].l+1)*node[k].lazy; node[rson].sum+=(node[rson].r-node[rson].l+1)*node[k].lazy; if(node[lson].flag)node[lson].flag+=node[k].lazy; if(node[rson].flag)node[rson].flag+=node[k].lazy; node[lson].lazy+=node[k].lazy; node[rson].lazy+=node[k].lazy; node[k].lazy=0; } return; } void Build(int l,int r,int k) { node[k].l=l; node[k].r=r; node[k].lazy=0; node[k].flag=0; if(l==r) { node[k].flag=node[k].sum=A[l]; return ; } int mid=(l+r)/2; Build(l,mid,lson); Build(mid+1,r,rson); pushup(k); return; } void update1(int l, int r, ll v, int k) { if(l<=node[k].l&&node[k].r<=r) { node[k].lazy+=v; if(node[k].flag) node[k].flag+=v; node[k].sum+=(node[k].r-node[k].l+1)*v; return; } int mid=(node[k].l+node[k].r)/2; pushdown(k); if(l<=mid)update1(l,min(mid,r),v,lson); if(r>mid)update1(max(l,mid+1),r,v,rson); pushup(k); } void update2(int l, int r, int k) { if(l<=node[k].l&&node[k].r<=r&&node[k].flag) { node[k].flag=sqrt(node[k].flag); node[k].sum=(node[k].r-node[k].l+1)*node[k].flag; return; } int mid=(node[k].l+node[k].r)/2; pushdown(k); if(l<=mid)update2(l,min(mid,r),lson); if(r>mid)update2(max(mid+1,l),r,rson); pushup(k); } ll getsum(int l,int r,int k) { ll sum1=0; ll sum2=0; if(l<=node[k].l&&node[k].r<=r) { return node[k].sum; } pushdown(k); int mid=(node[k].l+node[k].r)/2; if(l<=mid)sum1=getsum(l,min(mid,r),lson); if(r>mid)sum2=getsum(max(mid+1,l),r,rson); return sum1+sum2; } int main() { #ifndef ONLINE_JUDGE freopen("coco.txt", "r", stdin); freopen("lala.txt", "w", stdout); #endif T=Scan(); while(T--) { n=Scan(); m=Scan(); for(int i = 1; i <= n; i++) { A[i]=Scan(); } Build(1,n,1); while(m--) { op=Scan(); l=Scan(); r=Scan(); if(op == 1) { x=Scan(); update1(l,r,x,1); } else if(op == 2) { update2(l,r,1); } else if(op == 3) { Out(getsum(l,r,1)); puts(""); } } } return 0; }
AC代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define lson 2*k #define rson 2*k+1 typedef long long ll; const ll INF = 0x3f3f3f3f; const ll maxn = 1e5 + 10; ll Scan()//读入整数外挂. { ll res = 0, ch, flag = 0; if((ch = getchar()) == '-') //判断正负 flag = 1; else if(ch >= '0' && ch <= '9') //得到完整的数 res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9' ) res = res * 10 + ch - '0'; return flag ? -res : res; } void Out(ll a) //输出外挂 { if(a > 9) Out(a / 10); putchar(a % 10 + '0'); //prllf("\n"); } /*1.加上一个值 2.开根号 3.计算总值 */ int T; int n, m; int op; int l, r; ll x; ll A[maxn]; class Node { public: int l; int r; ll sum; ll b; ll s; ll lazy; ll flag;//用flag来判断是否有整段的值都是一样的. }; Node node[4 * maxn]; void pushup(int k) { if(node[lson].flag == node[rson].flag && node[lson].flag) { node[k].flag = node[lson].flag; } else node[k].flag = 0; node[k].sum = node[lson].sum + node[rson].sum; node[k].b = max(node[lson].b, node[rson].b); node[k].s = min(node[lson].s, node[rson].s); } void pushdown(int k) { if(node[k].flag) { node[lson].b = node[lson].s = node[lson].flag = node[k].flag; node[rson].b = node[rson].s = node[rson].flag = node[k].flag; node[lson].sum = (node[lson].r - node[lson].l + 1) * node[k].flag; node[rson].sum = (node[rson].r - node[rson].l + 1) * node[k].flag; node[k].lazy = 0; } if(node[k].lazy) { node[lson].sum += (node[lson].r - node[lson].l + 1) * node[k].lazy; node[rson].sum += (node[rson].r - node[rson].l + 1) * node[k].lazy; if(node[lson].flag)node[lson].flag += node[k].lazy; if(node[rson].flag)node[rson].flag += node[k].lazy; node[lson].b += node[k].lazy; node[lson].s += node[k].lazy; node[rson].b += node[k].lazy; node[rson].s += node[k].lazy; node[lson].lazy += node[k].lazy; node[rson].lazy += node[k].lazy; node[k].lazy = 0; } return; } void Build(int l, int r, int k) { node[k].l = l; node[k].r = r; node[k].lazy = 0; node[k].flag = 0; if(l == r) { node[k].b=node[k].s=node[k].flag = node[k].sum = A[l]; return ; } int mid = (l + r) / 2; Build(l, mid, lson); Build(mid + 1, r, rson); pushup(k); return; } void update1(int l, int r, ll v, int k) { if(l <= node[k].l && node[k].r <= r) { node[k].lazy += v; if(node[k].flag) node[k].flag += v; node[k].sum += (node[k].r - node[k].l + 1) * v; node[k].b += v; node[k].s += v; return; } int mid = (node[k].l + node[k].r) / 2; pushdown(k); if(l <= mid)update1(l, min(mid, r), v, lson); if(r > mid)update1(max(l, mid + 1), r, v, rson); pushup(k); } void update2(int l, int r, int k) { if(l <= node[k].l && node[k].r <= r) { if(node[k].flag) { node[k].flag = sqrt(node[k].flag); node[k].sum = (node[k].r - node[k].l + 1) * node[k].flag; node[k].b=node[k].flag; node[k].s=node[k].flag; return; } else if(node[k].b-node[k].s==1) { ll mb=node[k].b; ll ms=node[k].s; ll nb=sqrt(mb); ll ns=sqrt(ms); node[k].b=nb; node[k].s=ns; ll ml=node[k].sum-ms*(node[k].r-node[k].l+1); ll nl=(node[k].r-node[k].l+1)-ml; if( (nb-ns) == 1) { node[k].lazy+=(nb-mb); node[k].sum=nb*ml+ns*nl; } else { node[k].lazy=0; node[k].flag=nb; node[k].sum=(node[k].r-node[k].l+1)*nb; } return ; } } pushdown(k); int mid = (node[k].l + node[k].r) / 2; if(l <= mid)update2(l, min(mid, r), lson); if(r > mid)update2(max(mid + 1, l), r, rson); pushup(k); } ll getsum(int l, int r, int k) { ll sum1 = 0; ll sum2 = 0; if(l <= node[k].l && node[k].r <= r) { return node[k].sum; } pushdown(k); int mid = (node[k].l + node[k].r) / 2; if(l <= mid)sum1 = getsum(l, min(mid, r), lson); if(r > mid)sum2 = getsum(max(mid + 1, l), r, rson); return sum1 + sum2; } int main() { #ifndef ONLINE_JUDGE freopen("coco.txt", "r", stdin); freopen("lala.txt", "w", stdout); #endif T = Scan(); while(T--) { n = Scan(); m = Scan(); for(int i = 1; i <= n; i++) { A[i] = Scan(); } Build(1, n, 1); while(m--) { op = Scan(); l = Scan(); r = Scan(); if(op == 1) { x = Scan(); update1(l, r, x, 1); } else if(op == 2) { update2(l, r, 1); } else if(op == 3) { Out(getsum(l, r, 1)); printf("\n"); } } } return 0; }
相关文章推荐
- HDU 5828 多校第八场 1008 Rikka with Sequence(线段树--数据加强版)
- HDU 5828 Rikka with Sequence(线段树+小优化)
- hdu 5828 Rikka with Sequence 线段树
- HDU 5828 Rikka with Sequence
- HDU 5828 Rikka with Sequence(线段树)
- HDU 5828-H - Rikka with Sequence-线段树+玄学-区间开方/区间更新/区间求和
- hdu 5828 2016 Multi-University Training Contest 8 Rikka with Sequence 解题报告
- Hdu 5828 Rikka with Sequence
- HDU 5828 Rikka with Sequence (线段树)
- Hdu-5828 Rikka with Sequence(线段树)
- HDU 5828 Rikka with Sequence
- HDU-5828-Rikka with Sequence(线段树)
- HDU 5828 Rikka with Sequence(线段树 开根号)
- HDU 5828 Rikka with Sequence(线段树)
- HDU 5828 Rikka with Sequence 线段树优化
- HDU 5828 Rikka with Sequence 解题报告
- HDU 5828 Rikka with Sequence (线段树+剪枝优化)
- HDU 5828 Rikka with Sequence
- hdu 5828 Rikka with Sequence 【线段树+优化】
- 2016多校8 HDU 5828 Rikka with Sequence 线段树优化