BZOJ2874 训练士兵 主席树
【啊 首先 这是道权限题,然后本人显然是没有权限的 23咳3】
最近数据结构做的越来越少。。然后 就跟上次一样 ,一做就是三四种不同写法。
等价的题面:
最近GY大神在sc2的天梯中被神族虐得很惨,表示很不爽。ryz决定帮助GY大神练习散枪兵技术。GY生产了n*m个枪兵,并站成了一个大小为n*m的方阵。ryz生产了t个电兵(高阶圣堂武士),每个电兵能对一个矩形区域造成一定的AOE伤害(也就是对该矩形区域的每个枪兵都造成相等的伤害)。但是ryz的电兵实在太多了,以至于GY无法快速计算出一个矩形区域内枪兵受到的总伤害,于是他就不知道应该优先操作哪个位置的枪兵了。虽然GY大神只要1分钟就可以秒掉这道题,但是由于他正在操作枪兵,你需要写一个程序帮他解决这个问题。
输入格式:
第一行四个正整数n,m,t,q。
接下来t行,每行描述一个电兵。每行包括5个正整数x1,x2,y1,y2,d,表示对所有符合x1<=x<=x2,y1<=y<=y2的每个枪兵造成了d点伤害。
为了让同学们写更为有趣的在线询问算法,我把询问加密了,第1个询问的密码为0,第i+1个询问的密码为第i个询问的答案(mod 2^32)。
接下来q行,每行描述一个询问。每行包括2个正整数x,y。x1,x2,y1,y2按照以下方法计算(c表示该询问的密码):
x1=c % n+1,x2=(c+x) % n+1,如果x1>x2则交换x1和x2
y1=c % m+1,y2=(c+y) % m +1,如果y1>y2则交换y1和y2
你需要输出所有x1<=x<=x2,y1<=y<=y2的枪兵受到的总伤害(mod 2^32)。
输出格式:
对于每一个询问,输出一行答案mod 2^32的值。
样例输入:
4 5 3 2
1 3 2 2 7
2 4 2 3 5
1 4 4 5 6
1 2
0 3
样例输出:
24
12
数据范围:
对于20%的数据,m<=10
对于40%的数据,n,m<=50000,t<=30000,q<=30000
对于60%的数据,n,m<=10^5
对于另外20%的数据,所有电兵的y2-y1<=3
对于100%的数据,n,m<=10^8,t<=40000,q<=150000,d<=100000
时间限制:
5-6S (这时间应该是按测试点给的吧。。)
空间限制:
1G (exm?!)
。
。
。
作为曾经的数据结构狂热者。。现在大概是手感褪色。。
看到题 臆想 log方 ——好、裸题。 然后码农 最后GG。
那么 上一个GG的代码: 离散 横坐标,然后就二维线段树 空间显然过不了极限数据。时间也过不了。
#include <bits/stdc++.h>
#define U unsigned
using namespace std;
U n,m,t,T,Q,op[][],A[],B[],At,Bt,al,ar,bl,br,s,w,x,ans,a1,a2,b1,b2;
struct ala{ U l,r,p,q,e;}a[];
struct bla{ U l,r,ss,sw,ws,ww;}b[];
void build(U u){
if (a[u].p==a[u].q) return;
U i=a[u].p+a[u].q>>;
a[u].l=++t; a[t].p=a[u].p; a[t].q=i; build(t);
a[u].r=++t; a[t].p=i+; a[t].q=a[u].q; build(t);
}
U finda(U x){
U l=,r=At,j;
while (l<r){
j=l+r+>>;
A[j]<=x?l=j:r=j-;
}
return l;
}
void add(U &u,U p,U q,U l,U r){
if (!u) u=++t;
b[u].sw+=w*(U)(r-l+);
b[u].ss+=s*(U)(r-l+);
if (p==l&&q==r) {
b[u].ws+=s; b[u].ww+=w; return;
}
U i=p+q>>;
if (r<=i) add(b[u].l,p,i,l,r); else
if (l>i) add(b[u].r,i+,q,l,r); else
{add(b[u].l,p,i,l,i); add(b[u].r,i+,q,i+,r);}
}
void play(U u,U l,U r){
if (a[u].p==l&&a[u].q==r){
s=x*(U)(A[r+]-A[l]); w=x;
add(a[u].e,,m,bl,br);
return;
}
s=x*(A[r+]-A[l]); w=; add(a[u].e,,m,bl,br);
U i=a[u].p+a[u].q>>;
if (r<=i) play(a[u].l,l,r); else
if (l>i) play(a[u].r,l,r); else
{play(a[u].l,l,i); play(a[u].r,i+,r);}
}
U getw(U u,U p,U q,U l,U r){
if (!u) return ;
if (p==l&&q==r) return b[u].sw;
U x=(r-l+)*b[u].ww;
U i=p+q>>;
if (r<=i) return getw(b[u].l,p,i,l,r)+x;
if (l>i) return getw(b[u].r,i+,q,l,r)+x;
return getw(b[u].l,p,i,l,i)+getw(b[u].r,i+,q,i+,r)+x;
}
U gets(U u,U p,U q,U l,U r){
if (!u) return ;
if (p==l&&q==r) return b[u].ss;
U x=(r-l+)*b[u].ws;
U i=p+q>>;
if (r<=i) return gets(b[u].l,p,i,l,r)+x;
if (l>i) return gets(b[u].r,i+,q,l,r)+x;
return gets(b[u].l,p,i,l,i)+gets(b[u].r,i+,q,i+,r)+x;
}
U qiu(U u,U l,U r){
if (a[u].p==l&&a[u].q==r) return gets(a[u].e,,m,bl,br);
U x=getw(a[u].e,,m,bl,br)*(A[r+]-A[l]);
U i=a[u].p+a[u].q>>;
if (r<=i) return x+qiu(a[u].l,l,r);
if (l>i) return x+qiu(a[u].r,l,r);
return x+qiu(a[u].l,l,i)+qiu(a[u].r,i+,r);
}
U qiuw(U u,U l,U r){
if (a[u].p==l&&a[u].q==r) return getw(a[u].e,,m,bl,br);
U x=getw(a[u].e,,m,bl,br);
U i=a[u].p+a[u].q>>;
if (r<=i) return x+qiuw(a[u].l,l,r);
if (l>i) return x+qiuw(a[u].r,l,r);
return x+qiuw(a[u].l,l,i)+qiuw(a[u].r,i+,r);
}
int main(){
scanf("%u%u%u%u",&n,&m,&T,&Q);
for (U i=;i<=T;++i){
scanf("%u%u%u%u%u",&op[i][],&op[i][],&op[i][],&op[i][],&op[i][]);
if (op[i][]>op[i][]) swap(op[i][],op[i][]);
if (op[i][]>op[i][]) swap(op[i][],op[i][]);
A[i]=op[i][]; A[i+T]=op[i][]+;
}
A[T+T+]=;
sort(A+,A+T+T+);
for (U i=;i<=T+T+;++i){
if (A[i]!=A[i-]) ++At;
A[At]=A[i];
}
a[].p=; a[].q=At; build(t=); t=;
A[At+]=n+;
for (U i=;i<=T;++i){
al=finda(op[i][]); ar=finda(op[i][]);
bl=op[i][]; br=op[i][];
x=op[i][]; play(,al,ar);
}
while (Q--){
scanf("%u%u",&a2,&br);
a1=ans%n+; a2=(ans+a2)%n+;
bl=ans%m+; br=(ans+br)%m+;
if (a1>a2) swap(a1,a2);
if (bl>br) swap(bl,br);
al=finda(a1); ar=finda(a2); ans=;
if (al==ar)
ans=qiuw(,al,al)*(a2-a1+);
else{
if (al+<ar) ans+=qiu(,al+,ar-);
ans+=qiuw(,al,al)*(A[al+]-a1);
ans+=qiuw(,ar,ar)*(a2-A[ar]+);
}
printf("%u\n",ans);
}
return ;
}
Bad Apple!!
实际 只要主席树就可以一个log了。 对第一维排序离散,另一维动态开点主席树。记录到A这个坐标的 前缀信息和当前信息。
一个重要的事故。。输入的操作。数据范围有很多问题。。具体看代码
#include <bits/stdc++.h>
#define U unsigned
#define Ul unsigned long long
using namespace std;
struct opt{ U x,p,q; Ul w; }op[];
struct bla{ U l,r; Ul a,qs,ds,qw,dw; }b[];
bool cmp(opt a,opt b){return a.x<b.x;}
U n,m,T,Q,t,e[]; Ul A,W,ans,ax,bx,ay,by;
void add(U &u,U l,U r,U p,U q){
b[++t]=b[u]; u=t;
b[u].qs+=b[u].ds*(A-b[u].a);
b[u].qw+=b[u].dw*(A-b[u].a);
b[u].a=A; b[u].ds+=W*(r-l+);
if (l==p&&r==q){ b[u].dw+=W; return; }
U i=p+q>>;
if (r<=i) add(b[u].l,l,r,p,i); else
if (l>i) add(b[u].r,l,r,i+,q); else
{add(b[u].l,l,i,p,i); add(b[u].r,i+,r,i+,q);}
}
Ul get(U u,U l,U r,U p,U q){
if (!u) return ;
if (l==p&&q==r) return b[u].qs+b[u].ds*(A-b[u].a);
Ul ans=(b[u].qw+b[u].dw*(A-b[u].a))*(r-l+);
U i=p+q>>;
if (r<=i) return get(b[u].l,l,r,p,i)+ans;
if (l>i) return get(b[u].r,l,r,i+,q)+ans;
return get(b[u].l,l,i,p,i)+get(b[u].r,i+,r,i+,q)+ans;
}
Ul qiu(U x){
U l=,r=T,j; if (x<op[].x) return ;
if (x>=op[r].x) x=op[r].x;
while (l<r){
j=l+r+>>;
op[j].x<=x?l=j:r=j-;
}
A=x+; return get(e[l],ay,by,,m);
}
int main(){
scanf("%u%u%u%u",&n,&m,&T,&Q);
for (U i=;i<=T;++i){
U a,b,c,d; Ul e;
scanf("%u%u%u%u%llu",&a,&b,&c,&d,&e);
a=min(max((U),a),n); b=min(max((U),b),n);
c=min(max((U),c),m); d=min(max((U),d),m);
if (a>b) swap(a,b); if (c>d) swap(c,d);
op[i]={a,c,d,e}; op[i+T]={b+,c,d,-e};
} T<<=;
sort(op+,op++T,cmp);
for (U i=;i<=T;++i) A=op[i].x,W=op[i].w,e[i]=e[i-],add(e[i],op[i].p,op[i].q,,m);
while (Q--){
scanf("%llu%llu",&bx,&by);
ax=ans%n+; ay=ans%m+; bx=(ans+bx)%n+; by=(ans+by)%m+;
if (ax>bx) swap(ax,bx); if (ay>by) swap(ay,by);
ans=qiu(bx)-qiu(ax-); printf("%llu\n",ans);
}
return ;
}
Good Apple!!!
BZOJ2874 训练士兵 主席树的更多相关文章
- 2019.01.22 bzoj2874: 训练士兵(主席树)
传送门 题意简述:给出一个n∗mn*mn∗m的矩阵n,m≤1e8n,m\le1e8n,m≤1e8,支持矩形加,矩形求和,强制在线. 思路:第一眼二维动态开点线段树,上网去搜有没有这种做法发现会被卡时空 ...
- BZOJ2874 : 训练士兵
设$a[i][j]$表示$(i,j)$右下角要增加多少 $aj[i][j]=a[i][j]\times j$ $ai[i][j]=a[i][j]\times i$ $aij[i][j]=a[i][j] ...
- HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)
HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分) 传送门:http://acm.hdu.edu.cn/showproblem.php? ...
- Cutting Bamboos(2019年牛客多校第九场H题+二分+主席树)
题目链接 传送门 题意 有\(n\)棵竹子,然后有\(q\)次操作,每次操作给你\(l,r,x,y\),表示对\([l,r]\)区间的竹子砍\(y\)次,每次砍伐的长度和相等(自己定砍伐的高度\(le ...
- K-th Number Poj - 2104 主席树
K-th Number Poj - 2104 主席树 题意 给你n数字,然后有m次询问,询问一段区间内的第k小的数. 解题思路 这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简 ...
- 集训队8月1日(拓扑排序+DFS+主席树入门)
上午看书总结 今天上午我看了拓扑排序,DFS+剪枝,相当于回顾了一下,写了三个比较好的例题.算法竞赛指南93~109页. 1.状态压缩+拓扑排序 https://www.cnblogs.com/246 ...
- bzoj3207--Hash+主席树
题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...
- bzoj1901--树状数组套主席树
树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
随机推荐
- NYOJ-481平衡字符串
平衡字符串 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 给你一定长度的字符串.字符串中只包含26个小写字母,首先我们把字母a-z分为2堆(a--m)和(n--z),判 ...
- Java并发编程:自己动手写一把可重入锁
关于线程安全的例子,我前面的文章Java并发编程:线程安全和ThreadLocal里面提到了,简而言之就是多个线程在同时访问或修改公共资源的时候,由于不同线程抢占公共资源而导致的结果不确定性,就是在并 ...
- bzoj 1432 [ZJOI2009]Function 思想
[bzoj1432][ZJOI2009]Function Description Input 一行两个整数n; k. Output 一行一个整数,表示n 个函数第k 层最少能由多少段组成. Sampl ...
- jvm的类加载器,类装载过程
混沌初开,在一片名为jvm的世界中,到处都是一片虚无,直到一个名为BootstrapClassLoader的巨人劈开了世界,据说它是由名叫C++的女神所造,它从一个叫做jre/lib的宝袋中拿出一把开 ...
- 洛谷P2814 家谱(gen)
题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. 输入输出格式 输入格式: 输入由多行组成,首先是一系列有关父子关系的描述,其中每一组 ...
- hdu 2438 Turn the corner [ 三分 ]
传送门 Turn the corner Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- Ultra-QuickSort--POJ2299(归并排序求逆序数对)
http://poj.org/problem?id=2299 归并排序:比如现在有一个序列[l,r),我们可以把这个序列分成两个序列[l,mid),[mid,r),利用递归按照上 述方法逐步缩小序列, ...
- 使用Spring Data Redis操作Redis(单机版)
说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...
- 【Todo】秒杀系统 & 乐观锁 & Nginx反向代理
http://www.csdn.net/article/2014-11-28/2822858 1. 单点帐号验证,不用读,而是用写入,Redis,看是否加watch 2. 抢宝的最终购买冲突.包装称“ ...
- 【Git使用具体解释】Egit的经常使用操作具体解释
经常使用操作 操作 说明 Fetch 从远程获取最新版本号到本地,不会自己主动merge Merge 能够把一个分支标签或某个commit的改动合并如今的分支上 Pull 从远程获取最新版本号并mer ...