今天突然想写个树套树爽一爽(1810ms)

写的是树状数组套线段树(动态开节点)

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
const int maxnode=;
int sum[maxnode],ls[maxnode],rs[maxnode],ToT;
void update(int& y,int l,int r,int& pos,int& v)
{
if(!y) y=++ToT;
sum[y]+=v;if(l==r) return;
int mid=l+r>>;
if(pos<=mid) update(ls[y],l,mid,pos,v);
else update(rs[y],mid+,r,pos,v);
}
int ans;
void query(int& y,int l,int r,int& ql,int& qr)
{
if(ql<=l&&r<=qr) {ans+=sum[y];return;}
if(!y) return;
int mid=l+r>>;
if(ql<=mid) query(ls[y],l,mid,ql,qr);
if(qr>mid) query(rs[y],mid+,r,ql,qr);
}
int n,root[maxn],lastans;
void add(int x,int y,int v)
{
for(;x<=;x+=x&-x) update(root[x],,,y,v);
}
int query(int x,int ql,int qr)
{
ans=;
for(;x;x-=x&-x) query(root[x],,,ql,qr);
return ans;
}
int tp[],x1[],x2[],y1[],y2[],v[];
int tmp[],tot;
int main()
{
read();n=read();int m;
for(int i=;;i++)
{
tp[i]=read();
if(tp[i]==) {m=i;break;}
else if(tp[i]==) x1[i]=read(),y1[i]=read(),v[i]=read();
else x1[i]=read(),y1[i]=read(),x2[i]=read(),y2[i]=read(),tmp[++tot]=x2[i];
tmp[++tot]=x1[i];
}
sort(tmp+,tmp+tot+);
for(int i=;i<=m;i++) x1[i]=lower_bound(tmp+,tmp+tot+,x1[i])-tmp,x2[i]=lower_bound(tmp+,tmp+tot+,x2[i])-tmp;
tot=;for(int i=;i<=m;i++) tmp[++tot]=y1[i],tmp[++tot]=y2[i];sort(tmp+,tmp+tot+);
for(int i=;i<=m;i++) y1[i]=lower_bound(tmp+,tmp+tot+,y1[i])-tmp,y2[i]=lower_bound(tmp+,tmp+tot+,y2[i])-tmp;
for(int i=;i<=m;i++)
{
if(tp[i]==) break;
else if(tp[i]==) add(x1[i],y1[i],v[i]);
else printf("%d\n",query(x2[i],y1[i],y2[i])-query(x1[i]-,y1[i],y2[i]));
}
return ;
}

竟然还要离散TAT(maxnode开到2*10^8会RE,开到2.5*10^8会MLE)

这是之前写的CDQ分治(328ms)

代码难看勿喷

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
char ch;int sig;
inline void read(int& x)
{
ch=getchar(); sig=; x=;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') sig=-,ch=getchar();
while(isdigit(ch)) x=x*+ch-'',ch=getchar();
x*=sig;
}
const int maxn=;
struct Query
{
int t,x,y,v,id;
bool operator < (const Query& ths) const
{
return x<ths.x||(x==ths.x&&y<ths.y)||(x==ths.x&&y==ths.y&&t<ths.t);
}
}A[maxn],t1[maxn];
int ans[];
int w,s;
int C[];
void update(int x,int v)
{
for(;x<=w;x+=x&-x) C[x]+=v;
}
int query(int x)
{
int ret=;
for(;x;x-=x&-x) ret+=C[x];
return ret;
}
void solve(int L,int R)
{
if(L==R) return;
int m1=,m2=,M=L+R>>;
solve(L,M);
solve(M+,R);
for(int i=L;i<=M;i++) if(A[i].t==) t1[m1++]=A[i];
if(!m1) return;
m2=m1;
for(int i=M+;i<=R;i++) if(A[i].t==) t1[m2++]=A[i];
if(m2==m1) return;
sort(t1,t1+m2);
for(int i=;i<m2;i++)
{
if(t1[i].t==) update(t1[i].y,t1[i].v);
else ans[t1[i].id]+=t1[i].v*query(t1[i].y);
}
for(int i=;i<m2;i++) if(t1[i].t==) update(t1[i].y,-t1[i].v);
}
int main()
{
scanf("%d%d",&s,&w);
int x1,y1,x2,y2,t,a,tot=,n=;
while()
{
read(t);
if(t==) break;
if(t==)
{
read(x1); read(y1); read(a);
A[++tot]=(Query){t,x1,y1,a,};
}
else
{
read(x1); read(y1); read(x2); read(y2);
ans[++n]=(x2-x1+)*(y2-y1+)*s;
A[++tot]=(Query){t,x1-,y1-,,n};
A[++tot]=(Query){t,x2,y2,,n};
A[++tot]=(Query){t,x1-,y2,-,n};
A[++tot]=(Query){t,x2,y1-,-,n};
}
}
solve(,tot);
for(int i=;i<=n;i++) printf("%d\n",ans[i]);
return ;
}

YY了一个k-d树(625ms)

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
int lc[maxn],rc[maxn],x[maxn],y[maxn],mxx[maxn],mxy[maxn],mnx[maxn],mny[maxn],sum[maxn];
void maintain(int r)
{
mxx[r]=max(x[r],max(mxx[lc[r]],mxx[rc[r]]));
mnx[r]=min(x[r],min(mnx[lc[r]],mnx[rc[r]]));
mxy[r]=max(y[r],max(mxy[lc[r]],mxy[rc[r]]));
mny[r]=min(y[r],min(mny[lc[r]],mny[rc[r]]));
}
int x1,y1,x2,y2,v,ToT;
void insert(int& r,int d)
{
if(!r) r=++ToT,x[r]=mxx[r]=mnx[r]=x1,y[r]=mny[r]=mxy[r]=y1;
sum[r]+=v;
if(x[r]==x1&&y[r]==y1) return;
if(!d)
{
if(x1<=x[r]) insert(lc[r],d^);
else insert(rc[r],d^);
}
else
{
if(y1<=y[r]) insert(lc[r],d^);
else insert(rc[r],d^);
}
maintain(r);
}
int query(int r,int d)
{
if(!r) return ;
if(mnx[r]>=x1&&mxx[r]<=x2&&mny[r]>=y1&&mxy[r]<=y2) return sum[r];
int ret=;
if(x[r]<=x2&&x[r]>=x1&&y[r]<=y2&&y[r]>=y1) ret+=sum[r]-sum[lc[r]]-sum[rc[r]];
if(!d)
{
if(x1<=x[r]) ret+=query(lc[r],d^);
if(x2>x[r]) ret+=query(rc[r],d^);
}
else
{
if(y1<=y[r]) ret+=query(lc[r],d^);
if(y2>y[r]) ret+=query(rc[r],d^);
}
return ret;
}
int main()
{
read();int n=read(),root=;
mxx[]=mxy[]=-1e9;mnx[]=mny[]=1e9;
for(;;)
{
int tp=read();
if(tp==) break;
else if(tp==)
{
x1=read();y1=read();v=read();
insert(root,);
}
else
{
x1=read();y1=read();x2=read();y2=read();
printf("%d\n",query(root,));
}
}
return ;
}

最后写了写树状数组套Treap(1919ms)

#include<cstdio>
#include<cctype>
#include<cstring>
#include<ctime>
#include<algorithm>
using namespace std;
inline int read()
{
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
struct Node
{
Node* ch[];
int r,s,v,v2,sum;
void maintain() {s=ch[]->s+ch[]->s+;sum=v2+ch[]->sum+ch[]->sum;}
}nodes[maxn],*null=&nodes[];
int ToT;
void rotate(Node* &o,int d)
{
Node* k=o->ch[d^];o->ch[d^]=k->ch[d];k->ch[d]=o;
o->maintain();k->maintain();o=k;
}
void insert(Node* &o,int v,int v2)
{
if(o==null)
{
o=&nodes[++ToT];
o->r=rand();o->s=;o->v=v;o->v2=o->sum=v2;
o->ch[]=o->ch[]=null;
}
else
{
int d=v>o->v;
insert(o->ch[d],v,v2);
if(o->ch[d]->r>o->r) rotate(o,d^);
else o->maintain();
}
}
int query(Node* &o,int v)
{
if(o==null) return ;
if(v<=o->v) return query(o->ch[],v);
return o->ch[]->sum+o->v2+query(o->ch[],v);
}
Node* root[maxn];int n;
void add(int x,int y,int v)
{
for(;x<=n;x+=x&-x) insert(root[x],y,v);
}
int query(int x,int y1,int y2)
{
int ret=;
for(;x;x-=x&-x) ret+=query(root[x],y2+)-query(root[x],y1);
return ret;
}
int main()
{
srand(time());null->s=null->sum=;
read();n=read();
for(int i=;i<=n;i++) root[i]=null;
for(;;)
{
int tp=read();
if(tp==) break;
if(tp==)
{
int x=read(),y=read(),v=read();
add(x,y,v);
}
else
{
int x1=read(),y1=read(),x2=read(),y2=read();
printf("%d\n",query(x2,y1,y2)-query(x1-,y1,y2));
}
}
return ;
}

COJ1012 WZJ的数据结构(十二)的更多相关文章

  1. 算法与数据结构(十二) 散列(哈希)表的创建与查找(Swift版)

    散列表又称为哈希表(Hash Table), 是为了方便查找而生的数据结构.关于散列的表的解释,我想引用维基百科上的解释,如下所示: 散列表(Hash table,也叫哈希表),是根据键(Key)而直 ...

  2. COJ 1002 WZJ的数据结构(二)(splay模板)

    我的LCC,LCT,Splay格式终于统一起来了... 另外..这个形式的Splay是标准的Splay(怎么鉴别呢?看Splay函数是否只传了一个变量node就行),刘汝佳小白书的Splay写的真是不 ...

  3. [COJ0988]WZJ的数据结构(负十二)

    [COJ0988]WZJ的数据结构(负十二) 试题描述 输入 见题目,注意本题不能用文件输入输出 输出 见题目,注意本题不能用文件输入输出 输入示例 输出示例 数据规模及约定 1≤N≤1500,M≤N ...

  4. COJ968 WZJ的数据结构(负三十二)

    WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...

  5. [COJ0968]WZJ的数据结构(负三十二)

    [COJ0968]WZJ的数据结构(负三十二) 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着.请你设计一个数据结构,回答M次操作. 1 x:将节点x上的灯拉一次,即亮变 ...

  6. [COJ0985]WZJ的数据结构(负十五)

    [COJ0985]WZJ的数据结构(负十五) 试题描述 CHX有一个问题想问问大家.给你一个长度为N的数列A,请你找到两个位置L,R,使得A[L].A[L+1].…….A[R]中没有重复的数,输出R- ...

  7. COJ966 WZJ的数据结构(负三十四)

    WZJ的数据结构(负三十四) 难度级别:C: 运行时间限制:20000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给一棵n个节点的树,请对于形如"u  ...

  8. COJ970 WZJ的数据结构(负三十)

    WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...

  9. COJ986 WZJ的数据结构(负十四)

    WZJ的数据结构(负十四) 难度级别:D: 运行时间限制:6000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小 ...

随机推荐

  1. php如何将数组保存为文件的方法? 三个方法让你快速把数组保存成为文件存储

    php 缓存数组形式的变量,实际上就是将 php 将数组写入到一个文本文件或者后缀名为 .php 存储起来,使用的时候直接调用这个文件.那么如何使用 php 将数组保存为文本格式的文件呢?下面分享三种 ...

  2. CSS3.0盒模型display:-webkit-box;的使用

    box-flex是css3新添加的盒子模型属性,它的出现可以解决我们通过N多结构.css实现的布局方式.经典   的一个布局应用就是布局的垂直等高.水平均分.按比例划分. 目前box-flex属性还没 ...

  3. Java 7 的7个新特性

    1.对集合类的语言支持:(??) 2.自动资源管理: 3.改进的通用实例创建类型推断:(??) 4.数字字面量下划线支持:(√) 5.switch中使用string:(√) 6.二进制字面量:(√) ...

  4. 【转】Linux Shell脚本调试技术

    本文转载自:https://www.ibm.com/developerworks/cn/linux/l-cn-shell-debug/ Shell脚本调试技术 本文全面系统地介绍了shell脚本调试技 ...

  5. CSS 样式显示为小手

    因为工作需要把鼠标放上去显示小手形状, css样式如下: style="cursor:hand"    部分浏览器支持 style="cursor:pointer&quo ...

  6. tuple元组(C++11及以后,如C++14)

    类tuple与array最本质的区别当数tuple元组元素类型可以不一样,而统一数组array的元素类型必须一样. 本文主要举例: tuple_size Example 123456789101112 ...

  7. JavaScript字符串&数字间转换

    比较操作符的操作数可以是任意类型.然而,只有数字和字符串才能真正执行边角操作,因此那些不是数字和字符串的操作数都讲进行类型转换,类型转换规则如下:      如果操作数为对象,那么对象转换为原始值:如 ...

  8. C#开发微信公众平台-就这么简单(附Demo)(转载)

    转载地址:http://www.cnblogs.com/xishuai/p/3625859.html 写在前面 服务号和订阅号 URL配置 创建菜单 查询.删除菜单 接受消息 发送消息(图文.菜单事件 ...

  9. hdu 1541/poj 2352:Stars(树状数组,经典题)

    Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  10. C#控制管理VisualSVN Server

    VisualSVN Server可以用WMI接口管理(Windows Management Instrumentation). VisualSVN Server安装的计算机中,位于%VISUALSVN ...