您的位置:首页 > 理论基础 > 数据结构算法

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

2015-08-05 13:02 696 查看
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<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=200000+10,maxb=500,inf=-1u>>1;
int z[maxn],st[maxb],en[maxb],size,n,A[maxn],B[maxn],set[maxb],siz[maxb];
inline int read(){
int x=0,sig=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0;
for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
return sig?x:-x;
}
inline void write(int x){
if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');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]+1);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]+1,z[qr]-1,cv),sett(st[z[qr]],qr,cv);return;
}
int queryb(int L,int R,int cv){
int ans=0;
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]+1,cv)-B-st[b];
}return ans;
}
int queryt(int L,int R,int cv){
int ans=0;
if(set[z[L]]!=inf){
if(set[z[L]]<=cv)ans+=(R-L+1);
}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]+1,z[qr]-1,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=1;i<=n;i++){
A[i]=B[i]=read();
z[i]=(i-1)/size+1;
if(!st[z[i]])st[z[i]]=i;
en[z[i]]=i;
}
for(int b=1;b<=z
;b++)build(b),set[b]=inf,siz[b]=en[b]-st[b]+1;
for(int i=1;i<=n;i++){
tp=read();ql=read();qr=read();cv=read();
if(tp==2)write(queryo(ql,qr,cv)),ENT;
else seto(ql,qr,cv);
}
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){init();work();print();return 0;}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: