WZJ的数据结构(负三十三) |
难度级别:E; 运行时间限制: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 |
题解:标程肯定是什么线段树分治什么的奇怪的东西,窝不会写呀,,,就写分块吧,于是就虐标程了哦,excited!
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar(' ') 9 using namespace std; 10 const int maxn=200000+10,maxb=500,inf=-1u>>1; 11 int z[maxn],st[maxb],en[maxb],size,n,A[maxn],B[maxn],set[maxb],siz[maxb]; 12 inline int read(){ 13 int x=0,sig=1;char ch=getchar(); 14 for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0; 15 for(;isdigit(ch);ch=getchar())x=10*x+ch-'0'; 16 return sig?x:-x; 17 } 18 inline void write(int x){ 19 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 20 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 21 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 22 } 23 void build(int b){ 24 for(int i=st[b];i<=en[b];i++)B[i]=A[i];sort(B+st[b],B+en[b]+1);return; 25 } 26 void down(int b){ 27 if(set[b]!=inf){for(int i=st[b];i<=en[b];i++)A[i]=B[i]=set[b];set[b]=inf;}return; 28 } 29 void sett(int L,int R,int cv){ 30 down(z[L]);for(int i=L;i<=R;i++)A[i]=cv;build(z[L]);return; 31 } 32 void setb(int L,int R,int cv){ 33 for(int b=L;b<=R;b++)set[b]=cv;return; 34 } 35 void seto(int ql,int qr,int cv){ 36 if(z[ql]==z[qr])sett(ql,qr,cv); 37 else sett(ql,en[z[ql]],cv),setb(z[ql]+1,z[qr]-1,cv),sett(st[z[qr]],qr,cv);return; 38 } 39 int queryb(int L,int R,int cv){ 40 int ans=0; 41 for(int b=L;b<=R;b++){ 42 if(set[b]!=inf){ 43 if(set[b]<=cv)ans+=siz[b]; 44 }else ans+=upper_bound(B+st[b],B+en[b]+1,cv)-B-st[b]; 45 }return ans; 46 } 47 int queryt(int L,int R,int cv){ 48 int ans=0; 49 if(set[z[L]]!=inf){ 50 if(set[z[L]]<=cv)ans+=(R-L+1); 51 }else for(int i=L;i<=R;i++)if(A[i]<=cv)ans++; 52 return ans; 53 } 54 int queryo(int ql,int qr,int cv){ 55 if(z[ql]==z[qr])return queryt(ql,qr,cv); 56 else return queryt(ql,en[z[ql]],cv)+queryb(z[ql]+1,z[qr]-1,cv)+queryt(st[z[qr]],qr,cv); 57 } 58 void init(){ 59 n=read();size=sqrt((double)n*0.9);int tp,ql,qr,cv; 60 for(int i=1;i<=n;i++){ 61 A[i]=B[i]=read(); 62 z[i]=(i-1)/size+1; 63 if(!st[z[i]])st[z[i]]=i; 64 en[z[i]]=i; 65 } 66 for(int b=1;b<=z[n];b++)build(b),set[b]=inf,siz[b]=en[b]-st[b]+1; 67 for(int i=1;i<=n;i++){ 68 tp=read();ql=read();qr=read();cv=read(); 69 if(tp==2)write(queryo(ql,qr,cv)),ENT; 70 else seto(ql,qr,cv); 71 } 72 return; 73 } 74 void work(){ 75 return; 76 } 77 void print(){ 78 return; 79 } 80 int main(){init();work();print();return 0;}
总结一下这次WA的tip:queryt的时候窝萌是要暴力的呀。。。。。。。。。。。。
还有就是一开始没写B数组哦。。。。。。