卿学姐种花

Time Limit: 0/7500MS (Java/Others)     Memory Limit: 0/220000KB (Java/Others)

众所周知,在喵哈哈村,有一个温柔善良的卿学姐。

卿学姐喜欢和她一样美丽的花。所以卿学姐家的后院有很多的花坛。

卿学姐有nn个花坛,一开始第ii个花坛里有A[i]A[i]朵花。每过一段时间,卿学姐都会在花坛里种上新的花。

作为一个聪明的学姐,卿学姐的种花方式也是与众不同 , 每一次,卿学姐会在第xx个花坛种上yy朵花,然后在第x+1x+1个花坛上种上y−1y−1朵花,再在第x+2x+2个花坛上种上y−2y−2朵花......以此类推,直到种到最后一个花坛,或者不需要种花为止。

喵哈哈的村民们都喜欢去卿学姐的后院赏花,沈宝宝也不例外。然而沈宝宝可不是省油的灯,怎么可能会老老实实地赏花呢。每次沈宝宝来时,都会随机询问卿学姐在第ii个花坛有多少朵花。

花坛的花实在太多了,卿学姐实在是数不过来。于是现在她向你求助,希望你能帮她数出花坛里多少朵花。

Input

第一行输入两个整数,花坛个数NN和操作次数QQ。

第二行NN个整数A[1],A[2],A[3].....A[N]A[1],A[2],A[3].....A[N]。 ( 1≤A[i]≤2311≤A[i]≤231 )

接下来QQ行,每行一个操作。

  1. 1 x y 表示卿学姐会在xx号花坛种yy朵花,并按相应的规律在后面的花坛上种花。

  2. 2 x 表示沈宝宝问卿学姐第xx个花坛有多少朵花。

数据保证:

  • 1≤N≤1041≤N≤104

  • 1≤Q≤2∗1061≤Q≤2∗106

  • ∑x≤108∑x≤108,xx代表操作22 的询问下标

  • 对于操作 11 , 1≤x≤N1≤x≤N,1≤y≤1091≤y≤109

  • 对于操作 22 , 1≤x≤N1≤x≤N

Output

对于每个询问操作,按顺序输出答案对772002+233772002+233取模的值。

Sample input and output

Sample Input
Sample Output
6 3
1 2 3 2 1 2
1 2 3
2 3
2 6
5
2

Hint

第一次种花会在第22号花坛种33朵,第33号花坛种22朵,第44号花坛种11朵,由于在第55号花坛不用种花,所以就不再继续种花了,最终每个花坛花的数量分别为1,5,5,3,11,5,5,3,1。

思路:

一开始根本没想到使用线段树的,因为线段树都是要在相同的区间更新相同的值,所以感觉不像。但是想了好久暴力的方法都是预处理都会超时,最重要的是发现了一点,

那就是这个查询必须是在线的查询,所以可以肯定用线段树是可行的。之后就是要优化了。一开始想直接更新到叶子结点,结果TLE4,之后发现了原来多次输入都是可以累加

在一起的,所以就加多一个更新区间的次数就AC了。

TLE代码:

#include<iostream>
#include<functional>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define CRL(a) memset(a,0,sizeof(a))
#define QWQ ios::sync_with_stdio(0)
#define inf 0x3f3f3f3f
typedef unsigned long long LL;
typedef  long long ll;const int T = 10000+50;
const int mod = 1000000007;
const int mo = 772002+233;#define lson (rt<<1)
#define rson (rt<<1|1)ll n,m;
struct node
{ll v,lazy,tar;int L,R,mid;
}tree[T<<3];void Push_Down(int rt)
{if(tree[rt].lazy){if(tree[rt].L==tree[rt].R&&tree[rt].lazy){tree[rt].v += tree[rt].lazy - (tree[rt].L-tree[rt].tar);}else {tree[rson].lazy = tree[lson].lazy = tree[rt].lazy;tree[rson].tar = tree[lson].tar = tree[rt].tar;}tree[rt].lazy = 0;tree[rt].tar = 0;}
}void Build(int rt,int L,int R)
{tree[rt].L = L,tree[rt].R = R;tree[rt].mid = (L+R)>>1;tree[rt].tar = tree[rt].lazy = 0;if(L==R){scanf("%lld",&tree[rt].v);return;}Build(lson,L,tree[rt].mid);Build(rson,tree[rt].mid+1,R);
}void Insert(int rt,int L,int R,ll val,int tar)
{if(L<=tree[rt].L&&R>=tree[rt].R&&!tree[rt].lazy||tree[rt].L==tree[rt].R){Push_Down(rt);tree[rt].lazy = val;tree[rt].tar = tar;return;}//Push_Down(rt);if(R<=tree[rt].mid){Insert(lson,L,R,val,tar);}else if(L>tree[rt].mid){Insert(rson,L,R,val,tar);}else {Insert(lson,L,tree[rt].mid,val,tar);Insert(rson,tree[rt].mid+1,R,val,tar);}
}ll query(int rt,int pos)
{if(tree[rt].L==pos&&tree[rt].R==pos){if(tree[rt].lazy)return tree[rt].v + tree[rt].lazy - (pos-tree[rt].tar);return tree[rt].v;}if(pos<=tree[rt].mid){if(tree[rt].lazy)return query(lson,pos) + tree[rt].lazy - (pos-tree[rt].tar);return query(lson,pos);}else{if(tree[rt].lazy)return query(rson,pos) + tree[rt].lazy - (pos-tree[rt].tar);return query(rson,pos);}
}int main()
{#ifdef zscfreopen("input.txt","r",stdin);
#endifint i,j,k;while(~scanf("%lld%lld",&n,&m)){Build(1,1,n);ll num,u,v;for(i=0;i<m;++i){scanf("%lld",&num);if(num==1){scanf("%lld%lld",&u,&v);Insert(1,u,min(u+v-1,n),v,u);}else {scanf("%lld",&u);printf("%lld\n",query(1,u)%mo);}}}return 0;
}

TLE(在n=10^6TLE,10^4可以接受)代码:

这道算法题被改为n=10^6时,线段树被卡内存了,结果想到了分快做,结果又没考虑时间复杂度又太高了,醉了。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int T=1000000+50;
const int N=2000;
#define inf 0x3f3f3f3fL
#define mod 1000000000
typedef long long ll;
typedef unsigned long long ULL;int sz;
ll num[T],Delta[N];int main()
{
#ifdef zsc freopen("input.txt","r",stdin);
#endifint n,m,i,j,k;while(~scanf("%d%d",&n,&m)){sz = sqrt(n);for(i=0;i<n;++i){scanf("%lld",&num[i]);}int OP,x,y,tar,L,R;while(m--){scanf("%d",&OP);if(OP==1){scanf("%d%d",&x,&y);ll tmp = y;L = x,R = min(x+y,n);L--,R--;int LB=L/sz,RB=R/sz;for(i=min((LB+1)*sz-1,R);i>=L;--i){num[i] += tmp--;}if(tmp<=0)continue;for(i=LB+1;i<=RB-1;++i){Delta[i] += tmp;tmp -= sz;if(tmp<=0)break;}if(LB==RB||tmp<=0)continue;for(i=RB*sz;i<=R;++i){num[i] += tmp--;if(tmp<=0)break;}}else {scanf("%d",&tar);tar--;printf("%lld\n",num[tar]+Delta[tar/sz]);}}}return 0;
}

AC代码:

#include<iostream>
#include<functional>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define CRL(a) memset(a,0,sizeof(a))
#define QWQ ios::sync_with_stdio(0)
#define inf 0x3f3f3f3f
typedef unsigned long long LL;
typedef  long long ll;const int T = 10000+50;
const int mod = 1000000007;
const int mo = 772002+233;#define lson (rt<<1)
#define rson (rt<<1|1)ll n,m;
struct node
{ll v,lazy,tar,cnt;int L,R,mid;
}tree[T<<3];void Push_Down(int rt)//向下更新左右孩子
{if(tree[rt].lazy){tree[rson].lazy += tree[rt].lazy;tree[lson].lazy += tree[rt].lazy;tree[rson].cnt += tree[rt].cnt;tree[lson].cnt += tree[rt].cnt;tree[rson].tar += tree[rt].tar;tree[lson].tar += tree[rt].tar;tree[rt].lazy = 0;tree[rt].tar = 0;tree[rt].cnt = 0;}
}void Build(int rt,int L,int R)//建立二叉树
{tree[rt].L = L,tree[rt].R = R;tree[rt].mid = (L+R)>>1;tree[rt].cnt = 0;tree[rt].tar = tree[rt].lazy = 0;if(L==R){scanf("%lld",&tree[rt].v);return;}Build(lson,L,tree[rt].mid);Build(rson,tree[rt].mid+1,R);
}void Insert(int rt,int L,int R,ll val,int tar)
{if(L<=tree[rt].L&&R>=tree[rt].R){//当符合区间tree[rt].cnt++;tree[rt].lazy += val;tree[rt].tar += tar;return;}Push_Down(rt);if(R<=tree[rt].mid){Insert(lson,L,R,val,tar);}else if(L>tree[rt].mid){Insert(rson,L,R,val,tar);}else {Insert(lson,L,tree[rt].mid,val,tar);Insert(rson,tree[rt].mid+1,R,val,tar);}
}ll query(int rt,int pos)
{if(tree[rt].L==pos&&tree[rt].R==pos){//到叶子节点if(tree[rt].lazy)return tree[rt].v + tree[rt].lazy - (tree[rt].cnt*pos-tree[rt].tar);return tree[rt].v;}//之后一路回溯回去,如果路上存在数值就加上去if(pos<=tree[rt].mid){if(tree[rt].lazy)return query(lson,pos) + tree[rt].lazy - (tree[rt].cnt*pos-tree[rt].tar);return query(lson,pos);}else{if(tree[rt].lazy)return query(rson,pos) + tree[rt].lazy - (tree[rt].cnt*pos-tree[rt].tar);return query(rson,pos);}
}int main()
{#ifdef zscfreopen("input.txt","r",stdin);
#endifint i,j,k;while(~scanf("%lld%lld",&n,&m)){Build(1,1,n);ll num,u,v;for(i=0;i<m;++i){scanf("%lld",&num);if(num==1){//插入字符u与种v花scanf("%lld%lld",&u,&v);Insert(1,u,min(u+v-1,n),v,u);}else {//查询u位置的花scanf("%lld",&u);printf("%lld\n",query(1,u)%mo);}}}return 0;
}

卿学姐种花(线段树)相关推荐

  1. CDOJ 1292 卿学姐种花 暴力 分块 线段树

    卿学姐种花 题目连接: http://acm.uestc.edu.cn/#/problem/show/1292 Description 众所周知,在喵哈哈村,有一个温柔善良的卿学姐. 卿学姐喜欢和她一 ...

  2. CDOJ 1292 卿学姐种花(暴力,分块,线段树)

    众所周知,在喵哈哈村,有一个温柔善良的卿学姐. 卿学姐喜欢和她一样美丽的花.所以卿学姐家的后院有很多的花坛. 卿学姐有n 个花坛,一开始第 i个花坛里有 A[i] 朵花.每过一段时间,卿学姐都会在花坛 ...

  3. CDOJ 1292 卿学姐种花(分块)

    题目链接:点击打开链接 思路: 由于是一个区间更新问题, 而且更新的值不一样, 所以我们考虑分块.  对于一个块, 我们维护第i块的第一个元素被加了多少了sum[i],第i块被更新了多少次cnt[i] ...

  4. A - 卿学姐与公主(线段树+单点更新+区间极值)

    A - 卿学姐与公主 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  5. 卿学姐与公主(线段树区间求最大值)

    A - 卿学姐与公主 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  6. 2016 UESTC Training for Data Structures O - 卿学姐种美丽的花 树状数组+等差数列

    O - 卿学姐种美丽的花 Time Limit: 8000/4000MS (Java/Others)     Memory Limit: 125535/65535KB (Java/Others) Su ...

  7. cdoj1344卿学姐种美丽的花

    地址:http://acm.uestc.edu.cn/#/problem/show/1344 题目: 卿学姐种美丽的花 Time Limit: 8000/4000MS (Java/Others)    ...

  8. D - 卿学姐与魔法

    卿学姐与魔法 Time Limit: 1200/800MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  9. Uestc1291 上天的卿学姐【状压dp】

    Description 众所周知,卿学姐十分擅长数据结构. 一天卿学姐开始研究起二维偏序的问题,卿学姐三下五除二就写了个树状数组解决了. 于是卿学姐开始做三维的问题,搞了个树套树也是过了. 欲求不满的 ...

最新文章

  1. 赠书 | 图解机器学习算法,看这文就够了!
  2. Android之本地数据存储(一):SharedPreferences
  3. check_mk自定义监控实践之powershell
  4. GDCM:gdcm::System的测试程序
  5. topcoder srm 714 div1
  6. 钉钉宜搭邵磊:钉钉宜搭低代码加速业务互联 让改变发生
  7. 批处理命令——for
  8. UVALive - 7147 (数学)
  9. java 针式打印_JAVA针式打印机打印整理
  10. NRF24L01入门总结
  11. Qt截取长图(带滚动条被遮挡部分需要展开截取全图)QScrollArea、QPixmap
  12. 3月大修之后 Flash的安全问题继续被诟病?
  13. Kafka彻底删除topic详解
  14. CASAIM全自动3d测量仪自动检测差速器差壳全尺寸测量装配检测
  15. win10所有文件夹都是只读
  16. AI实战:垂直领域问答机器人QA Bot常见技术架构
  17. Android MD5加密法
  18. 本地搭建xxl-job服务及连接验证
  19. 如何用Python找出英语和汉语中特定词性的单词
  20. 在javaweb中将excel表格导入存放数据库

热门文章

  1. 视频教程-Office Project 2019教程-Office/WPS
  2. linux下的arp刷新命令详解,linux arp 命令常用参数详解
  3. iOS NSDate等时间类的使用
  4. steam Depot 生成与应用脚本
  5. LSTM做文本生成(基于word2vec)
  6. 【量化金融】20220820_银行行业市盈率(TTM)的报告
  7. android 无法隐藏键盘,我无法在Android上隐藏虚拟键盘
  8. 小米 OJ 编程比赛 03 月常规赛 小爱密码 2.0
  9. 2021-05-代购如何做引流?有哪些雷区要注意?26
  10. 方法 | 帮你培养沉稳气质的三个诀窍