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 |
一上午的青春全部奉献给这道题了(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
相关文章推荐
- 数据结构04:树与二叉树
- 数据结构实验之栈:行编辑器
- hdu 5316 多校(3)
- 数据结构——各类排序算法总结
- 数据结构实验之栈三:后缀式求值 SDUT 2133
- 代码整洁之道--对象和数据结构
- 数据结构入门——动态数组
- 数据结构入门——栈与队列
- 数据结构入门——链表的实现
- 【黑马程序员-学习笔记】数据结构-顺序表
- 数据结构入门——递归
- Twemproxy源码分析(四)数据结构(array和string)
- Twemproxy源码分析(三)数据结构(队列)
- 基本数据结构和算法回顾
- 数据结构基础温故-6.查找(上):基本查找与树表查找
- 数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树
- STL库的容器简要总结
- 队列的实现---数据结构学习(五)
- 数据结构之查找算法总结笔记
- 数据结构实验之链表七:单链表中重复元素的删除