COJ967 WZJ的数据结构(负三十三)

时间:2023-01-17 16:33:19
WZJ的数据结构(负三十三)
难度级别:C; 运行时间限制:7000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

请你设计一个数据结构,完成以下功能:

给定一个大小为N的整数组A,要求你回答执行N次操作。操作分两种:

操作1:每次操作给你l,r,v三个参数,求Al至Ar中值<=v的个数。

操作2:每次操作给你l,r,v三个参数,将Al至Ar所有数的值设为v。

输入
第一行为一个正整数N。
第二行为N个整数Ai。
接下来N行每行4个正整数t,l,r,v。若t=2表示操作1,t=1表示操作2。
输出
对每个操作1输出结果。
输入示例
6
1 2 2 1 2 3
2 1 4 2
2 1 4 1
1 2 4 1
2 1 4 1
1 3 5 2
2 2 5 2
输出示例
4
2
4
4
其他说明
1<=N<=200000
1<=Ai,v<=10^9

XYZ大爷论文题“一个简单的序列问题”。

一上午的青春全部奉献给这道题了(3棵线段树调得我要报警)。

先将区间修改转化成带删除的区间插入,用一棵线段树来做。

再用线段树分治将问题转化成静态问题,用一棵线段树和2个nlogn的邻接表。

最后排序后转化成区间加与区间查询的问题,用一棵线段树来做。

说起来真是简单呢!

#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i!=-1;i=next[i])
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 Query {
int tp,l,r,x,begin,end,id;
bool operator < (const Query& ths) const {return begin<ths.begin;}
}Q[maxn],Q2[maxn*];
struct Solver {
int id,l,r,x;
bool operator < (const Solver& ths) const {return x<ths.x||(x==ths.x&&id<ths.id);}
}A[maxn*];
int n,ans[maxn],m;
int setv[maxn*],is[maxn*];
void pushdown(int o) {
int lc=o<<,rc=lc|;
if(setv[o]) {
setv[lc]=setv[rc]=setv[o];
is[lc]=is[rc]=;
setv[o]=;
}
}
int lastv,L,R;
void find(int o,int l,int r,int v) {
if(!is[o]) return;
if(setv[o]) {
if(setv[o]==lastv) R=r;
else {
if(lastv!=-) Q2[++m]=(Query){,L,R,Q[lastv].x,lastv,v-,Q[lastv].id};
lastv=setv[o];L=l;R=r;
}
setv[o]=;
}
else if(l<r) {
int mid=l+r>>,lc=o<<,rc=lc|;
find(lc,l,mid,v);find(rc,mid+,r,v);
}
is[o]=;
}
void update(int o,int l,int r,int ql,int qr,int v) {
if(ql<=l&&r<=qr) find(o,l,r,v),setv[o]=v;
else {
pushdown(o);
int mid=l+r>>,lc=o<<,rc=lc|;
if(ql<=mid) update(lc,l,mid,ql,qr,v);
if(qr>mid) update(rc,mid+,r,ql,qr,v);
}
is[o]=;
}
int first1[maxn*],next1[maxn*],id1[maxn*],ToT1;
int first2[maxn*],next2[maxn*],id2[maxn*],ToT2,N;
void query(int o,int l,int r,int pos,int v) {
N=max(N,o);
id1[++ToT1]=v;next1[ToT1]=first1[o];first1[o]=ToT1;
if(l==r) return;
int mid=l+r>>,lc=o<<,rc=lc|;
if(pos<=mid) query(lc,l,mid,pos,v);
else query(rc,mid+,r,pos,v);
}
void modify(int o,int l,int r,int ql,int qr,int v) {
N=max(N,o);
if(ql<=l&&r<=qr) {
id2[++ToT2]=v;next2[ToT2]=first2[o];first2[o]=ToT2;
}
else {
int mid=l+r>>,lc=o<<,rc=lc|;
if(ql<=mid) modify(lc,l,mid,ql,qr,v);
if(qr>mid) modify(rc,mid+,r,ql,qr,v);
}
}
int addv[maxn*],sumv[maxn*];
void pushdown2(int o,int l,int r) {
int mid=l+r>>,lc=o<<,rc=lc|;
if(addv[o]) {
addv[lc]+=addv[o];addv[rc]+=addv[o];
sumv[lc]+=addv[o]*(mid-l+);sumv[rc]+=addv[o]*(r-mid);
addv[o]=;
}
}
void update2(int o,int l,int r,int ql,int qr,int v) {
int mid=l+r>>,lc=o<<,rc=lc|;
if(ql<=l&&r<=qr) addv[o]+=v;
else {
pushdown2(o,l,r);
if(ql<=mid) update2(lc,l,mid,ql,qr,v);
if(qr>mid) update2(rc,mid+,r,ql,qr,v);
}
if(l<r) sumv[o]=sumv[lc]+sumv[rc];
else sumv[o]=;
if(addv[o]) sumv[o]+=addv[o]*(r-l+);
}
int query2(int o,int l,int r,int ql,int qr) {
if(ql<=l&&r<=qr) return sumv[o];
pushdown2(o,l,r);
int mid=l+r>>,lc=o<<,rc=lc|,ans=;
if(ql<=mid) ans+=query2(lc,l,mid,ql,qr);
if(qr>mid) ans+=query2(rc,mid+,r,ql,qr);
return ans;
}
int tmp[maxn];
int main() {
n=read();
rep(i,,n) Q[Q[i].id=i].tp=,Q[i].l=i,Q[i].r=i,Q[i].x=read();
rep(i,n+,*n) Q[Q[i].id=i].tp=read(),Q[i].l=read(),Q[i].r=read(),Q[i].x=read();
n<<=;
Q[n+].tp=;Q[n+].l=;Q[n+].r=n>>;
rep(i,,n+) {
if(Q[i].tp==) {
lastv=-;
update(,,n>>,Q[i].l,Q[i].r,i);
if(lastv!=-) Q2[++m]=(Query){,L,R,Q[lastv].x,lastv,i-,Q[lastv].id};
}
else Q2[++m]=Q[i],Q2[m].begin=Q2[m].end=i;
}
rep(i,,m) {
if(Q2[i].tp==) modify(,,n,Q2[i].begin,Q2[i].end,i);
else query(,,n,Q2[i].begin,i);
}
rep(i,,N) if(first1[i]&&first2[i]) {
int cnt=;
for(int j=first1[i];j;j=next1[j]) A[++cnt]=(Solver){Q2[id1[j]].id,Q2[id1[j]].l,Q2[id1[j]].r,Q2[id1[j]].x};
for(int j=first2[i];j;j=next2[j]) A[++cnt]=(Solver){,Q2[id2[j]].l,Q2[id2[j]].r,Q2[id2[j]].x};
sort(A+,A+cnt+);
rep(j,,cnt) {
if(!A[j].id) update2(,,n>>,A[j].l,A[j].r,);
else ans[A[j].id]+=query2(,,n>>,A[j].l,A[j].r);
}
rep(j,,cnt) if(!A[j].id) update2(,,n>>,A[j].l,A[j].r,-);
}
rep(i,,n) if(Q[i].tp==) printf("%d\n",ans[i]);
return ;
}

8.6重写了一遍,30min写完,WA了两处233.

错误:

void pushdown(int o) {
int lc=o<<,rc=lc|;
if(setv[o]) {
setv[lc]=setv[rc]=;//setv[o]
is[lc]=is[rc]=;
setv[o]=;
}
} int query(int o,int l,int r,int ql,int qr) {
if(ql<=l&&r<=qr) return sumv[o];
//pushdown(o,l,r);
int mid=l+r>>,lc=o<<,rc=lc|,res=;
if(ql<=mid) res+=query(lc,l,mid,ql,qr);
if(qr>mid) res+=query(rc,mid+,r,ql,qr);
return res;
}

8.10啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊标程被分块虐了!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,maxb=,inf=-1u>>;
int z[maxn],st[maxb],en[maxb],size,n,A[maxn],B[maxn],set[maxb],siz[maxb];
inline int read(){
int x=,sig=;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=;
for(;isdigit(ch);ch=getchar())x=*x+ch-'';
return sig?x:-x;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
void build(int b){
for(int i=st[b];i<=en[b];i++)B[i]=A[i];sort(B+st[b],B+en[b]+);return;
}
void down(int b){
if(set[b]!=inf){for(int i=st[b];i<=en[b];i++)A[i]=B[i]=set[b];set[b]=inf;}return;
}
void sett(int L,int R,int cv){
down(z[L]);for(int i=L;i<=R;i++)A[i]=cv;build(z[L]);return;
}
void setb(int L,int R,int cv){
for(int b=L;b<=R;b++)set[b]=cv;return;
}
void seto(int ql,int qr,int cv){
if(z[ql]==z[qr])sett(ql,qr,cv);
else sett(ql,en[z[ql]],cv),setb(z[ql]+,z[qr]-,cv),sett(st[z[qr]],qr,cv);return;
}
int queryb(int L,int R,int cv){
int ans=;
for(int b=L;b<=R;b++){
if(set[b]!=inf){
if(set[b]<=cv)ans+=siz[b];
}else ans+=upper_bound(B+st[b],B+en[b]+,cv)-B-st[b];
}return ans;
}
int queryt(int L,int R,int cv){
int ans=;
if(set[z[L]]!=inf){
if(set[z[L]]<=cv)ans+=(R-L+);
}else for(int i=L;i<=R;i++)if(A[i]<=cv)ans++;
return ans;
}
int queryo(int ql,int qr,int cv){
if(z[ql]==z[qr])return queryt(ql,qr,cv);
else return queryt(ql,en[z[ql]],cv)+queryb(z[ql]+,z[qr]-,cv)+queryt(st[z[qr]],qr,cv);
}
void init(){
n=read();size=sqrt((double)n*0.9);int tp,ql,qr,cv;
for(int i=;i<=n;i++){
A[i]=B[i]=read();
z[i]=(i-)/size+;
if(!st[z[i]])st[z[i]]=i;
en[z[i]]=i;
}
for(int b=;b<=z[n];b++)build(b),set[b]=inf,siz[b]=en[b]-st[b]+;
for(int i=;i<=n;i++){
tp=read();ql=read();qr=read();cv=read();
if(tp==)write(queryo(ql,qr,cv)),ENT;
else seto(ql,qr,cv);
}
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){init();work();print();return ;}

COJ967 WZJ的数据结构(负三十三)的更多相关文章

  1. COJ 0967 WZJ的数据结构(负三十三)

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

  2. COJ 1003 WZJ的数据结构(三)ST表

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

  3. 数据结构(三十三)最小生成树(Prim、Kruskal)

    一.最小生成树的定义 一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边. 在一个网的所有生成树中,权值总和最小的生成树称为最小代价生成树(Minimum ...

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

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

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

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

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

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

  7. COJ969 WZJ的数据结构(负三十一)

    WZJ的数据结构(负三十一) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 A国有两个主基站,供给全国的资源.定义一个主基站 ...

  8. COJ 0970 WZJ的数据结构(负三十)树分治

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

  9. &lbrack;COJ0968&rsqb;WZJ的数据结构(负三十二)

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

随机推荐

  1. result结果集

    结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等. 结果集读取数据 ...

  2. Android UI详解之Fragment加载

    使用Fragment的原因: 1. Activity间的切换不流畅 2. 模块化Activity,方便做局部动画(有时为了到达这一点要把多个布局放到一个activity里面,现在可以用多Fragmen ...

  3. dpkg -P &lt&semi;pkg&gt&semi;

    http://www.linuxquestions.org/questions/debian-26/how-do-i-get-rid-of-those-rc-packages-as-seen-in-d ...

  4. jquery之效果操作

    jQuery操作之效果 效果一共分五大类 一.基本 二.滑动 三.淡入淡出 四.自定义 五.设置 咱们先来看一下基本类 一.基本又分为 show() hide() toggle() html代码 &l ...

  5. hadoop端口使用配置总结(非常好的总结)

    转自http://www.aboutyun.com/thread-7513-1-1.html Hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于RPC访问以 ...

  6. javascript&lpar;面向对象,作用域,闭包,设计模式等&rpar;

    javascript(面向对象,作用域,闭包,设计模式等) 1. 常用js类定义的方法有哪些? 参考答案:主要有构造函数原型和对象创建两种方法.原型法是通用老方法,对象创建是ES5推荐使用的方法.目前 ...

  7. SCOM中的通配符

    通配符模式匹配按从左到右的方式完成,一次匹配一个字符或基本通配符模式.模式和传入字符串必须完全匹配,因此,举例来说,模式“abc”与字符串“abcd”不匹配.复合模式包含由 (&) 号或波形符 ...

  8. Undirected Graphs

    无向图 Introduction 图是由边连接的点的集合,有着广泛的应用空间. 一些图的术语,点,边,路径,环(圈),连通分量(子图). 简单路径不重复经过点,简单环不含有重复点和边,简单图不含自环和 ...

  9. 工作JS总结

    获取 <inpout type="checkbox" value="1" /> 多选项的value /*获取checkbox的全部选中项 使用方法: ...

  10. Zookeeper启动失败:java&period;net&period;BindException&colon; Address already in use

    错误日志如下: [hadoop@master zookeeper-3.4.5-cdh5.10.0]$ cat zookeeper.out 2018-05-15 01:29:21,036 [myid:] ...