NOIWC前的交流题目汇总
RT
2018.12.27
i207M:BZOJ 4695 最假女选手
以维护最大值为例,记录最大值和严格次大值和最大值的出现次数,然后取min的时候递归到小于最大值但大于次大值修改,这个就是最重要的地方,剩下的就是码码码调调调
1 #include<cstdio> 2 #include<cctype> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=500005,M=2000005,inf=1e9; 7 int maxx[M],smax[M],cnt1[M]; 8 int mini[M],smin[M],cnt2[M]; 9 int a[N],laz[M]; long long val[M]; 10 int n,m,f,op,t1,t2,t3; 11 void read(int &x) 12 { 13 x=0,f=0; char ch=getchar(); 14 while(!isdigit(ch)) 15 f|=ch=='-',ch=getchar(); 16 while(isdigit(ch)) 17 x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); 18 x=f?-x:x; 19 } 20 void write(long long x) 21 { 22 if(x>9) write(x/10); 23 putchar(x%10|48); 24 } 25 void w(long long x) 26 { 27 if(x<0) putchar('-'),x=-x; 28 write(x),puts(""); 29 } 30 void Pushup(int nde) 31 { 32 int ls=2*nde,rs=2*nde+1; 33 val[nde]=val[ls]+val[rs]; 34 if(maxx[ls]==maxx[rs]) 35 maxx[nde]=maxx[ls],smax[nde]=max(smax[ls],smax[rs]),cnt1[nde]=cnt1[ls]+cnt1[rs]; 36 else 37 { 38 if(maxx[ls]<maxx[rs]) swap(ls,rs); 39 maxx[nde]=maxx[ls],smax[nde]=max(smax[ls],maxx[rs]),cnt1[nde]=cnt1[ls]; 40 } 41 if(mini[ls]==mini[rs]) 42 mini[nde]=mini[ls],smin[nde]=min(smin[ls],smin[rs]),cnt2[nde]=cnt2[ls]+cnt2[rs]; 43 else 44 { 45 if(mini[ls]>mini[rs]) swap(ls,rs); 46 mini[nde]=mini[ls],smin[nde]=min(smin[ls],mini[rs]),cnt2[nde]=cnt2[ls]; 47 } 48 } 49 void Apply(int nde,int l,int r,int tsk,int opt) 50 { 51 if(!opt) 52 { 53 maxx[nde]+=tsk,smax[nde]+=tsk; 54 mini[nde]+=tsk,smin[nde]+=tsk; 55 laz[nde]+=tsk,val[nde]+=1ll*tsk*(r-l+1); 56 } 57 else if(opt==1) 58 { 59 val[nde]+=1ll*(tsk-mini[nde])*cnt2[nde]; 60 mini[nde]=tsk,maxx[nde]=max(maxx[nde],tsk); 61 if(mini[nde]==maxx[nde]) 62 { 63 val[nde]=1ll*tsk*(r-l+1); 64 cnt1[nde]=cnt2[nde]=r-l+1; 65 smax[nde]=-inf,smin[nde]=inf; 66 } 67 else smax[nde]=max(smax[nde],tsk); 68 } 69 else if(opt==2) 70 { 71 val[nde]-=1ll*(maxx[nde]-tsk)*cnt1[nde]; 72 maxx[nde]=tsk,mini[nde]=min(mini[nde],tsk); 73 if(mini[nde]==maxx[nde]) 74 { 75 val[nde]=1ll*tsk*(r-l+1); 76 cnt1[nde]=cnt2[nde]=r-l+1; 77 smax[nde]=-inf,smin[nde]=inf; 78 } 79 else smin[nde]=min(smin[nde],tsk); 80 } 81 } 82 void Release(int nde,int l,int r) 83 { 84 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 85 if(laz[nde]) 86 { 87 Apply(ls,l,mid,laz[nde],0); 88 Apply(rs,mid+1,r,laz[nde],0),laz[nde]=0; 89 } 90 if(mini[ls]<mini[nde]&&smin[ls]>mini[nde]) Apply(ls,l,mid,mini[nde],1); 91 if(mini[rs]<mini[nde]&&smin[rs]>mini[nde]) Apply(rs,mid+1,r,mini[nde],1); 92 if(maxx[ls]>maxx[nde]&&smax[ls]<maxx[nde]) Apply(ls,l,mid,maxx[nde],2); 93 if(maxx[rs]>maxx[nde]&&smax[rs]<maxx[nde]) Apply(rs,mid+1,r,maxx[nde],2); 94 } 95 void Create(int nde,int l,int r) 96 { 97 if(l==r) 98 { 99 maxx[nde]=mini[nde]=val[nde]=a[l]; 100 smax[nde]=-inf,smin[nde]=inf,cnt1[nde]=cnt2[nde]=1; 101 } 102 else 103 { 104 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 105 Create(ls,l,mid),Create(rs,mid+1,r),Pushup(nde); 106 } 107 } 108 void Add(int nde,int l,int r,int nl,int nr,int tsk) 109 { 110 if(l>nr||r<nl) 111 return ; 112 else if(l>=nl&&r<=nr) 113 Apply(nde,l,r,tsk,0); 114 else 115 { 116 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde,l,r); 117 Add(ls,l,mid,nl,nr,tsk),Add(rs,mid+1,r,nl,nr,tsk),Pushup(nde); 118 } 119 } 120 void Maxi(int nde,int l,int r,int nl,int nr,int tsk) 121 { 122 if(l>nr||r<nl||mini[nde]>=tsk) 123 return ; 124 else if(l>=nl&&r<=nr&&smin[nde]>tsk) 125 Apply(nde,l,r,tsk,1); 126 else 127 { 128 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde,l,r); 129 Maxi(ls,l,mid,nl,nr,tsk),Maxi(rs,mid+1,r,nl,nr,tsk),Pushup(nde); 130 } 131 } 132 void Mini(int nde,int l,int r,int nl,int nr,int tsk) 133 { 134 if(l>nr||r<nl||maxx[nde]<=tsk) 135 return ; 136 else if(l>=nl&&r<=nr&&smax[nde]<tsk) 137 Apply(nde,l,r,tsk,2); 138 else 139 { 140 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde,l,r); 141 Mini(ls,l,mid,nl,nr,tsk),Mini(rs,mid+1,r,nl,nr,tsk),Pushup(nde); 142 } 143 } 144 long long Query(int nde,int l,int r,int nl,int nr,int opt) 145 { 146 if(l>nr||r<nl) 147 { 148 if(!opt) return 0; 149 else if(opt==1) return -inf; 150 else if(opt==2) return inf; 151 } 152 else if(l>=nl&&r<=nr) 153 { 154 if(!opt) return val[nde]; 155 else if(opt==1) return maxx[nde]; 156 else if(opt==2) return mini[nde]; 157 } 158 else 159 { 160 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde,l,r); 161 if(!opt) return Query(ls,l,mid,nl,nr,opt)+Query(rs,mid+1,r,nl,nr,opt); 162 else if(opt==1) return max(Query(ls,l,mid,nl,nr,opt),Query(rs,mid+1,r,nl,nr,opt)); 163 else if(opt==2) return min(Query(ls,l,mid,nl,nr,opt),Query(rs,mid+1,r,nl,nr,opt)); 164 } 165 } 166 int main() 167 { 168 read(n); register int i; 169 for(i=1;i<=n;i++) read(a[i]); 170 Create(1,1,n),read(m); 171 for(i=1;i<=m;i++) 172 { 173 read(op),read(t1),read(t2); 174 if(op==1) read(t3),Add(1,1,n,t1,t2,t3); 175 else if(op==2) read(t3),Maxi(1,1,n,t1,t2,t3); 176 else if(op==3) read(t3),Mini(1,1,n,t1,t2,t3); 177 else if(op==4) w(Query(1,1,n,t1,t2,0)); 178 else if(op==5) w(Query(1,1,n,t1,t2,1)); 179 else if(op==6) w(Query(1,1,n,t1,t2,2)); 180 } 181 return 0; 182 }
AubRain:CF993E Nikita and Order Statistics
转换成01序列变成了子区间和问题,然后对值域上的序列反过来做卷积
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=800005,M=40; 7 const double pai=acos(-1); 8 struct cpx 9 { 10 double x,y; 11 }a[N],b[N]; 12 cpx operator + (cpx c1,cpx c2) 13 { 14 return (cpx){c1.x+c2.x,c1.y+c2.y}; 15 } 16 cpx operator - (cpx c1,cpx c2) 17 { 18 return (cpx){c1.x-c2.x,c1.y-c2.y}; 19 } 20 cpx operator * (cpx c1,cpx c2) 21 { 22 double x1=c1.x,x2=c2.x,y1=c1.y,y2=c2.y; 23 return (cpx){x1*x2-y1*y2,x1*y2+x2*y1}; 24 } 25 double Sin[M],Cos[M]; 26 int rev[N],lgg[N]; 27 int n,x,m,nm,rd,sum; 28 void write(long long x) 29 { 30 if(x>9) write(x/10); 31 putchar(x%10|48); 32 } 33 void Prework() 34 { 35 scanf("%d%d",&n,&x),a[0].x=1; 36 for(int i=1;i<=n;i++) 37 { 38 scanf("%d",&rd); 39 sum+=rd<x,a[sum].x+=1; 40 } 41 for(int i=0;i<=n;i++) 42 b[n-i].x=a[i].x; 43 nm=n,n*=2,m=1,lgg[1]=0; while(m<=n) m<<=1; 44 for(int i=1;i<=m;i++) 45 rev[i]=(rev[i>>1]>>1)+(i&1)*(m>>1); 46 for(int i=2;i<=m;i++) 47 lgg[i]=lgg[i>>1]+1; 48 for(int i=1;i<=24;i++) 49 Sin[i]=sin(2*pai/(1<<i)),Cos[i]=cos(2*pai/(1<<i)); 50 } 51 void Trans(cpx *c,int t) 52 { 53 for(int i=0;i<m;i++) 54 if(rev[i]>i) swap(c[rev[i]],c[i]); 55 for(int i=2;i<=m;i<<=1) 56 { 57 int len=i>>1; 58 cpx omg={Cos[lgg[i]],Sin[lgg[i]]*t}; 59 for(int j=0;j<m;j+=i) 60 { 61 cpx ori={1,0},tmp; 62 for(int k=j;k<j+len;k++,ori=ori*omg) 63 tmp=ori*c[k+len],c[k+len]=c[k]-tmp,c[k]=c[k]+tmp; 64 } 65 } 66 if(t==-1) for(int i=0;i<=m;i++) c[i].x/=m; 67 } 68 long long Round(double x) 69 { 70 return (long long)(x+0.5); 71 } 72 int main() 73 { 74 Prework(); 75 Trans(a,1),Trans(b,1); 76 for(int i=0;i<=m;i++) a[i]=a[i]*b[i]; 77 Trans(a,-1); 78 write(Round((a[nm].x-nm-1)/2)),putchar(' '); 79 for(int i=nm+1;i<=n;i++) 80 write(Round(a[i].x)),putchar(' '); 81 return 0; 82 }