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

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数组哦。。。。。。

原文地址:https://www.cnblogs.com/chxer/p/4717039.html