LOJ分块⑨题汇总
从零开始的分块学习系列(感谢hzwer)
题目顺序是我建议的做题顺序
先说一句:分块的核心思想(其实本身分块就可以说是一种思想)是:均摊(或者说平衡/权衡?)复杂度,同时这种思想本身不只局限于序列分块(前一篇解题里有提到)
序列分块之①
区间加法+单点查询
分块入门题
知道分块的思想之后应该都会做,对整块打标记,对不超过块大小的零散区间暴力修改;查询的时候就是原数+所在块的标记
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=;
int a[N],blo[N],laz[Sq],pts[Sq][];
int n,m,t1,t2,t3,t4,cnt,sqr;
int main()
{
scanf("%d",&n),m=n;
pts[cnt=][]=,sqr=sqrt(n)+;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
blo[i]=(i-)/sqr+;
if(i%sqr==)
{
pts[cnt++][]=i;
pts[cnt][]=i+;
}
}
pts[cnt][]=n;
while(m--)
{
scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
if(!t1)
{
if(blo[t2]!=blo[t3])
{
for(int i=t2;i<=pts[blo[t2]][];i++) a[i]+=t4;
for(int i=blo[t2]+;i<=blo[t3]-;i++) laz[i]+=t4;
for(int i=pts[blo[t3]][];i<=t3;i++) a[i]+=t4;
}
else
for(int i=t2;i<=t3;i++) a[i]+=t4;
}
else
printf("%d\n",a[t3]+laz[blo[t3]]);
}
return ;
}
序列分块之④
区间加法+区间求和
用来熟悉分块的题目
和上一题差不多,还是整块打标记+零散区间暴力,只需再对每个块维护一个总和即可
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=;
long long laz[Sq],pts[Sq][];
long long a[N],blo[N],sum[Sq];
long long n,m,t1,t2,t3,t4,cnt,sqr;
int main()
{
scanf("%lld",&n),m=n;
sqr=sqrt(n)+,pts[cnt=][]=;
for(int i=;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=;i<=n;i++)
{
blo[i]=(i-)/sqr+;
sum[blo[i]]+=a[i];
if(i%sqr==)
{
pts[cnt++][]=i;
pts[cnt][]=i+;
}
}
pts[cnt][]=n;
while(m--)
{
scanf("%lld%lld%lld%lld",&t1,&t2,&t3,&t4);
if(!t1)
{
if(blo[t2]!=blo[t3])
{
for(int i=t2;i<=pts[blo[t2]][];i++) a[i]+=t4,sum[blo[i]]+=t4;
for(int i=blo[t2]+;i<=blo[t3]-;i++) laz[i]+=t4;
for(int i=pts[blo[t3]][];i<=t3;i++) a[i]+=t4,sum[blo[i]]+=t4;
}
else
for(int i=t2;i<=t3;i++) a[i]+=t4,sum[blo[i]]+=t4;
}
else
{
long long ans=;
if(blo[t2]!=blo[t3])
{
for(int i=t2;i<=pts[blo[t2]][];i++) ans=(ans+a[i]+laz[blo[i]])%(t4+);
for(int i=blo[t2]+;i<=blo[t3]-;i++)
ans=(ans+sum[i]+laz[i]*(pts[i][]-pts[i][]+)%(t4+))%(t4+);
for(int i=pts[blo[t3]][];i<=t3;i++) ans=(ans+a[i]+laz[blo[i]])%(t4+);
}
else
for(int i=t2;i<=t3;i++) ans=(ans+a[i]+laz[blo[i]])%(t4+);
printf("%lld\n",ans);
}
}
return ;
}
序列分块之⑦
区间加法+区间乘法+单点查询
仍然是熟悉分块的题目(因为这些能用线段树解决的问题一般我们不写分块=。=),不过新出现了一种做分块时的常见操作
和线段树的打标记差不多,打两个标记。然后对于整块的修改:加法只修改加法标记,乘法把加法乘法标记一起修改了。然后就发现对于零散区间不好处理标记,但是每次的零散区间总长不会超过$2*sqrt(n)$,所以直接把零散区间暴力重构然后清空标记,仍然可以保证复杂度。查询就挺简单的,不说了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=;
const long long mod=;
long long n,m,t1,t2,t3,t4,cnt;
long long a[N],blo[N],laz[Sq][],pts[Sq][];
void rebuild(int b,int l,int r,int v,int t)
{
for(int i=pts[b][];i<=pts[b][];i++)
a[i]=(a[i]*laz[b][]%mod+laz[b][])%mod;
laz[b][]=,laz[b][]=;
if(!t) for(int i=l;i<=r;i++) a[i]=(a[i]+v)%mod;
else for(int i=l;i<=r;i++) a[i]=a[i]*v%mod;
}
int main()
{
scanf("%lld",&n),m=n;
sqr=sqrt(n)+,pts[cnt=][]=;
for(int i=;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=;i<=n;i++)
{
blo[i]=(i-)/sqr+;
if(i%sqr==)
{
pts[cnt++][]=i;
pts[cnt][]=i+;
}
}
pts[cnt][]=n;
for(int i=;i<=cnt;i++) laz[i][]=;
while(m--)
{
scanf("%lld%lld%lld%lld",&t1,&t2,&t3,&t4);
if(!t1)
{
if(blo[t2]!=blo[t3])
{
rebuild(blo[t2],t2,pts[blo[t2]][],t4,);
rebuild(blo[t3],pts[blo[t3]][],t3,t4,);
for(int i=blo[t2]+;i<=blo[t3]-;i++) laz[i][]=(laz[i][]+t4)%mod;
}
else rebuild(blo[t2],t2,t3,t4,);
}
else if(t1==)
{
if(blo[t2]!=blo[t3])
{
rebuild(blo[t2],t2,pts[blo[t2]][],t4,);
rebuild(blo[t3],pts[blo[t3]][],t3,t4,);
for(int i=blo[t2]+;i<=blo[t3]-;i++)
laz[i][]=laz[i][]*t4%mod,laz[i][]=laz[i][]*t4%mod;
}
else rebuild(blo[t2],t2,t3,t4,);
}
else
printf("%lld\n",(a[t3]*laz[blo[t3]][]%mod+laz[blo[t3]][])%mod);
}
return ;
}
序列分块之⑧
区间查询等于某个值的元素个数,然后再把整个区间赋成这个元素
真正开始进入分块的核心思想的题目
好了,大部分的数据结构应该是GG了(也许有什么神仙数据结构能做),怎么破?
想想开头的那句话
我们可以发现,因为每次是把整个区间改成一个数,所以:
对于被整块覆盖的区间,我们好像只能暴力修改?莫慌,分析一下:如果它中间有很多个数,我们暴力修改完之后可以把整块打上标记,下次再查到这个块就直接$O(1)$统计了;如果它已经有标记了,那就更好了,直接$O(1)$统计+改标记即可
然后发现零散区间好像很麻烦,按照以往的套路我们还应该暴力修改它们,然而改完了之后区间的标记就没了,情感上好像复杂度不能接受
那我们理性分析一下
暴力修改一次最多只会破坏两个块的标记,这样至少经过$O(sqrt(n))$这个级别的修改后整个序列才又回到了初始的没标记的情况,这时候我们才会有$O(n)$的序列暴力修改,所以其实复杂度是$O(n$ $sqrt(n))$的,可以通过
这就是我开头所谓的“权衡/平衡复杂度”了
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=;
int n,m,t1,t2,t3,t4,sqr,cnt;
int a[N],blo[N],laz[Sq][],pts[Sq][];
int rebuild(int b,int l,int r,int v)
{
int ret=;
if(laz[b][])
{
laz[b][]=(laz[b][]==v);
for(int i=pts[b][];i<=pts[b][];i++)
a[i]=laz[b][];
}
for(int i=l;i<=r;i++)
ret+=(a[i]==v),a[i]=v;
return ret;
}
int main ()
{
scanf("%d",&n),m=n;
sqr=sqrt(n)+,pts[cnt=][]=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
blo[i]=(i-)/sqr+;
if(i%sqr==)
{
pts[cnt++][]=i;
pts[cnt][]=i+;
}
}
pts[cnt][]=n;
while(m--)
{
int ans=;
scanf("%d%d%d",&t1,&t2,&t3);
if(blo[t1]!=blo[t2])
{
ans+=rebuild(blo[t1],t1,pts[blo[t1]][],t3);
ans+=rebuild(blo[t2],pts[blo[t2]][],t2,t3);
for(int i=blo[t1]+;i<=blo[t2]-;i++)
if(laz[i][])
ans+=(pts[i][]-pts[i][]+)*(laz[i][]==t3),laz[i][]=t3;
else
{
laz[i][]=true,laz[i][]=t3;
for(int j=pts[i][];j<=pts[i][];j++)
ans+=(a[j]==t3),a[j]=t3;
}
}
else ans+=rebuild(blo[t1],t1,t2,t3);
printf("%d\n",ans);
}
return ;
}
序列分块之⑤
区间开平方+区间求和
感觉是对上一题的一个巩固
其实很多人应该做过这个题的线段树版本;用分块做这个题和上一个题有点类似(其实好像比上一个题简单,但是上一个题才真正地体现出分块的核心思想)。同样是(全部)暴力修改+在块上打标记,在整块都变成$0$或$1$之后这个块再开平方就不变了,所以跳过这种块即可。而一个数开平方是下降地非常快的,开平方的次数基本可以看做一个常数,这样总体也是$O(n$ $sqrt(n))$的
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=;
int n,m,t1,t2,t3,t4,cnt,sqr;
int a[N],blo[N],sum[Sq];
int laz[Sq],pts[Sq][];
int main ()
{
scanf("%d",&n),m=n;
sqr=sqrt(n)+,pts[cnt=][]=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
blo[i]=(i-)/sqr+;
sum[blo[i]]+=a[i];
if(i%sqr==)
{
pts[cnt++][]=i;
pts[cnt][]=i+;
}
}
pts[cnt][]=n;
while(m--)
{
scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
if(!t1)
{
if(blo[t2]!=blo[t3])
{
for(int i=t2;i<=pts[blo[t2]][];i++)
sum[blo[i]]-=a[i],a[i]=(int)sqrt(a[i]),sum[blo[i]]+=a[i];
for(int i=blo[t2]+;i<=blo[t3]-;i++)
if(!laz[i])
{
int lazy=true;
for(int j=pts[i][];j<=pts[i][];j++)
{
sum[i]-=a[j],a[j]=(int)sqrt(a[j]),sum[i]+=a[j];
if(a[j]&&a[j]!=) lazy=false;
}
if(lazy) laz[i]=true;
}
for(int i=pts[blo[t3]][];i<=t3;i++)
sum[blo[i]]-=a[i],a[i]=(int)sqrt(a[i]),sum[blo[i]]+=a[i];
}
else
for(int i=t2;i<=t3;i++)
sum[blo[i]]-=a[i],a[i]=(int)sqrt(a[i]),sum[blo[i]]+=a[i];
}
else
{
int ans=;
if(blo[t2]!=blo[t3])
{
for(int i=t2;i<=pts[blo[t2]][];i++) ans+=a[i];
for(int i=blo[t2]+;i<=blo[t3]-;i++) ans+=sum[i];
for(int i=pts[blo[t3]][];i<=t3;i++) ans+=a[i];
}
else for(int i=t2;i<=t3;i++) ans+=a[i];
printf("%d\n",ans);
}
}
return ;
}
序列分块之⑥
单点插入+单点查询
也是一道体现着分块的思想的题(虽然平衡树也可以做),这里我们会稍微转到序列分块⑦那里提到的一个做法,不过也沿用了一些上两题的思想
我们分块后把每个块装进一个vector里,然后直接用vector在对应位置插入。发现问题是当很多次插入之后一个块的vector可能会非常长,导致插入的复杂度变得很大;所以我们在一个vector超过某个长度$limit$(理论上是$2*sqrt(n)$,不过一会会说一些其他的东西)之后直接把所有vector清空,重构整个序列!类似序列分块⑧地分析:这样每最坏每$limit$次插入后会来一次$O(n)$的重构,所以复杂度是$O(n(\frac{n}{limit}+limit))$的。
看起来$limit$只要加上往常的块大小设置为$2*sqrt(n)$即可。不过实际情况中因为vector的常数实在太大了,导致暴力重构效率较低,所以其实把$limit$设得大一些反而效率更高=。=(我最后设的$10*sqrt(n)$)
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=;
int n,m,t1,t2,t3,t4,sqr,cnt,a[N];
vector<int> v[Sq];
pair<int,int> query(int pos)
{
int noww=;
while(pos>=(int)v[noww].size())
pos-=(int)v[noww++].size();
return make_pair(pos,noww);
}
void rebuild()
{
int p=;
for(int i=;i<=cnt;i++)
{
for(int j=;j<(int)v[i].size();j++)
a[++p]=v[i][j];
v[i].clear();
}
sqr=sqrt(p)+,cnt=(p-)/sqr+;
for(int i=;i<=p;i++)
v[(i-)/sqr+].push_back(a[i]);
}
int main ()
{
scanf("%d",&n),m=n;
sqr=sqrt(n)+,cnt=(n-)/sqr+;
for(int i=;i<=n;i++)
{
scanf("%d",&t1);
v[(i-)/sqr+].push_back(t1);
}
while(m--)
{
scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
if(!t1)
{
pair<int,int> q=query(t2-);
int pos=q.first,blo=q.second;
v[blo].insert(v[blo].begin()+pos,t3);
if((int)v[blo].size()>*sqr) rebuild();
}
else
{
pair<int,int> q=query(t3-);
int pos=q.first,blo=q.second;
printf("%d\n",v[blo][pos]);
}
}
return ;
}
Update on 2018.11.14:蒟蒻博主发现序列分块②③⑨的块大小其实不太对,应该是$sqrt(\frac{n}{\log n})$,然而我的是$sqrt(\frac{n}{\ln n})$,不过最近LOJ老出锅就懒得改了
序列分块之②
区间加法+查询区间小于某个数的元素之和
做到这里应该有点感觉了吧quq
还是个套路的做法,把每个块装进一个vector里,然后排好序。每次修改对于零散区间暴力清空然后重构vector,对于整块的打上标记
注意这时候有了排序的操作,我们分块的大小应该跟着变成$O(sqrt(n/log$ $n))$,复杂度$O(nlog$ $n$ $sqrt(nlog$ $n))$
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=;
int n,m,t1,t2,t3,t4,sqr,cnt;
int a[N],blo[N],laz[Sq],pts[Sq][];
vector<int> v[Sq];
void rebuild(int b,int l,int r,int t)
{
for(int i=l;i<=r;i++) a[i]+=t;
v[b].clear();
for(int i=pts[b][];i<=pts[b][];i++)
v[b].push_back(a[i]);
sort(v[b].begin(),v[b].end());
}
int main()
{
scanf("%d",&n),m=n;
sqr=sqrt(n)+,pts[cnt=][]=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
blo[i]=(i-)/sqr+;
v[blo[i]].push_back(a[i]);
if(i%sqr==)
{
pts[cnt++][]=i;
pts[cnt][]=i+;
}
}
pts[cnt][]=n;
for(int i=;i<=cnt;i++)
sort(v[i].begin(),v[i].end());
while(m--)
{
scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
if(!t1)
{
if(blo[t2]!=blo[t3])
{
rebuild(blo[t2],t2,pts[blo[t2]][],t4);
rebuild(blo[t3],pts[blo[t3]][],t3,t4);
for(int i=blo[t2]+;i<=blo[t3]-;i++) laz[i]+=t4;
}
else rebuild(blo[t2],t2,t3,t4);
}
else
{
int ans=; t4*=t4;
if(blo[t2]!=blo[t3])
{
for(int i=t2;i<=pts[blo[t2]][];i++)
if(a[i]+laz[blo[i]]<t4) ans++;
for(int i=blo[t2]+;i<=blo[t3]-;i++)
ans+=lower_bound(v[i].begin(),v[i].end(),t4-laz[i])-v[i].begin();
for(int i=pts[blo[t3]][];i<=t3;i++)
if(a[i]+laz[blo[i]]<t4) ans++;
}
else
for(int i=t2;i<=t3;i++)
if(a[i]+laz[blo[i]]<t4) ans++;
printf("%d\n",ans);
}
}
return ;
}
序列分块之③
区间加法+区间查询某个数的前驱
和上一题挺像的quq
修改时暴力重构零散区间+整块打标记,查询时仍然暴力重构零散区间+块内二分,然后还是注意块的大小
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=;
int a[N],blo[N],tmp[N];
int laz[Sq],pts[Sq][];
int n,m,t1,t2,t3,t4,cnt,sqr;
vector<int> v[Sq];
void rebuild(int b,int l,int r,int t)
{
for(int i=l;i<=r;i++) a[i]+=t;
v[b].clear();
for(int i=pts[b][];i<=pts[b][];i++)
v[b].push_back(a[i]);
sort(v[b].begin(),v[b].end());
}
int check(int b,int l,int r,int t)
{
int p=;
for(int i=l;i<=r;i++)
tmp[p++]=a[i]+laz[b];
sort(tmp,tmp+p);
int pos=lower_bound(tmp,tmp+p,t)-tmp-;
return (~pos)?tmp[pos]:-;
}
int main()
{
scanf("%d",&n),m=n;
sqr=sqrt(n)+,pts[cnt=][]=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
blo[i]=(i-)/sqr+;
v[blo[i]].push_back(a[i]);
if(i%sqr==)
{
pts[cnt++][]=i;
pts[cnt][]=i+;
}
}
pts[cnt][]=n;
for(int i=;i<=cnt;i++)
sort(v[i].begin(),v[i].end());
while(m--)
{
scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
if(!t1)
{
if(blo[t2]!=blo[t3])
{
rebuild(blo[t2],t2,pts[blo[t2]][],t4);
rebuild(blo[t3],pts[blo[t3]][],t3,t4);
for(int i=blo[t2]+;i<=blo[t3]-;i++) laz[i]+=t4;
}
else
rebuild(blo[t2],t2,t3,t4);
}
else
{
int ans=-;
if(blo[t2]!=blo[t3])
{
ans=max(ans,check(blo[t2],t2,pts[blo[t2]][],t4));
ans=max(ans,check(blo[t3],pts[blo[t3]][],t3,t4));
for(int i=blo[t2]+;i<=blo[t3]-;i++)
{
int pos=lower_bound(v[i].begin(),v[i].end(),t4-laz[i])-v[i].begin()-;
if(~pos) ans=max(ans,v[i][pos]+laz[i]);
}
}
else
ans=max(ans,check(blo[t2],t2,t3,t4));
printf("%d\n",ans);
}
}
return ;
}
序列分块之⑨
静态区间众数(听说陈立杰做到过$O(n^{\frac{5}{3}})$的带修区间众数 orz)
(其实我们平时用分块写的大多是这样的题)
注意到答案只可能是整块的众数或者出现在零散区间的数
先离散化,预处理$mde[i][j]$表示第$i$块与第$j$块间的众数(以每个块为起点开个桶扫一遍,复杂度$O(n$ $sqrt(n))$),然后把每种数的位置塞进一个对应的vector里,这样对于零散区间就可以直接二分了,复杂度$O(nlog$ $n$ $sqrt(nlog$ $n))$
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,Sq=,inf=;
int a[N],uni[N],blo[N],tmp[N],pts[Sq][],mde[Sq][Sq];
int n,m,t1,t2,cnt,sqr,mem,ans;
vector<int> pos[N];
bool better(int c1,int v1,int c2,int v2)
{
return (c1>c2||(c1==c2&&v1<v2));
}
void prework()
{
sort(uni+,uni++n);
int len=unique(uni+,uni++n)-uni-;
for(int i=;i<=n;i++)
{
a[i]=lower_bound(uni+,uni++len,a[i])-uni;
pos[a[i]].push_back(i);
}
for(int i=;i<=cnt;i++)
{
int ncnt=,nnum=inf;
memset(tmp,,sizeof tmp);
for(int j=pts[i][];j<=n;j++)
{
tmp[a[j]]++;
if(better(tmp[a[j]],a[j],ncnt,nnum))
ncnt=tmp[a[j]],nnum=a[j];
mde[i][blo[j]]=nnum;
}
}
}
int ask(int v)
{
vector<int>::iterator rr=upper_bound(pos[v].begin(),pos[v].end(),t2);
vector<int>::iterator ll=lower_bound(pos[v].begin(),pos[v].end(),t1);
return rr-ll;
}
void force(int l,int r)
{
for(int i=l;i<=r;i++)
{
int qry=ask(a[i]);
if(better(qry,a[i],mem,ans))
mem=qry,ans=a[i];
}
return ;
}
int main ()
{
scanf("%d",&n),m=n;
sqr=sqrt((double)n/log(n)),pts[cnt=][]=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]),uni[i]=a[i];
blo[i]=(i-)/sqr+;
if(i%sqr==)
{
pts[cnt++][]=i;
pts[cnt][]=i+;
}
}
pts[cnt][]=n; prework();
while(m--)
{
mem=,ans=inf;
scanf("%d%d",&t1,&t2);
if(blo[t1]!=blo[t2])
{
if(blo[t1]+<=blo[t2]-)
{
mem=ask(mde[blo[t1]+][blo[t2]-]);
ans=mde[blo[t1]+][blo[t2]-];
}
force(t1,pts[blo[t1]][]),force(pts[blo[t2]][],t2);
}
else force(t1,t2);
printf("%d\n",uni[ans]);
}
return ;
}
LOJ分块⑨题汇总的更多相关文章
- NOIP模拟题汇总(加厚版)
\(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...
- 老男孩IT教育-每日一题汇总
老男孩IT教育-每日一题汇总 第几天 第几周 日期 快速访问链接 第123天 第二十五周 2017年8月25日 出现Swap file….already exists以下错误如何解决? 第122天 2 ...
- 网络流 24 题汇总(LOJ 上只有 22 题???)
太裸的我就不放代码了...(黑体字序号的题表示值得注意) 1.搭配飞行员 [LOJ#6000] 二分图最大匹配. 2.太空飞行计划 [LOJ#6001] 最小割常规套路.输出方案.(注:这题换行符要用 ...
- [LOJ] 分块九题 6
单点插入,单点查询. 优化了的链表. 链表老写错,干脆用vector,也不算慢. 注意链表退化的问题,及时(比如操作根号n次)就重新建块,实测速度可以提高一倍,这还是数据随机的情况,若涉及大量同一位置 ...
- [LOJ] 分块九题 4
https://loj.ac/problem/6280 区间修改,区间求和. 本来线段树的活. //Stay foolish,stay hungry,stay young,stay simple #i ...
- [LOJ] 分块九题 3
https://loj.ac/problem/6279 区间修改,区间查询前驱. TLE无数,我觉得这代码最精髓的就是block=1000. 谜一样的1000. 两个启示: 块内可以维护数据结构,比如 ...
- [LOJ] 分块九题 2
https://loj.ac/problem/6278 区间修改,查询区间第k大. 块内有序(另存),块内二分. 还是用vector吧,数组拷贝排序,下标搞不来.. //Stay foolish,st ...
- [LOJ] 分块九题 1
https://loj.ac/problem/6277 区间修改,单点查询. //Stay foolish,stay hungry,stay young,stay simple #include< ...
- [LOJ] 分块九题 8
区间查询数值+整体赋值 维护tag代表整个区间被赋成了tag[i] 用pushdown操作,而不是修改了再check. 不压缩代码了,调起来心累,长点有啥不好. //Stay foolish,stay ...
随机推荐
- selenium,unittest——下拉菜单操作,百度账号设置修改
#encoding=utf-8from selenium import webdriverimport time,unittest, re,sysfrom HTMLTestRunner import ...
- Switch Game :因子数
A - Switch Game Problem Description There are many lamps in a line. All of them are off at first. A ...
- SPP-net论文总结
SPPNet方法来自<Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition> ,是大神 ...
- 实验一 MiniOS
实验一.命令解释程序的编写实验 商软1班 杨晶晶 201406114102 一. 实验目的 (1)掌握命令解释程序的原理: (2)掌握简单的DOS调用方法: (3)掌握C语言编程初 ...
- 20181113-3 Beta阶段贡献分配规则
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2382 在新成员加入后,我们经过商讨,决定沿用alpha阶段贡献分分配规则 ...
- Numpy and Pandas
安装 视频链接:https://morvanzhou.github.io/tutorials/data-manipulation/np-pd/ pip install numpy pip instal ...
- CodeForces 479C Exams 贪心
题目: C. Exams time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- 我是IT小小鸟读书笔记
阅读了我是IT小小鸟后发现,自己开发程序是真的很苦难的,在现在这个空对空的时期,我们学习到大部分的全都是理论知识,而没有真正的去进行实践.没有经过实践,我们在程序开发过程中也就无法发现自身的困难. 在 ...
- 关于mysql无法添加中文数据的问题以及解决方案
今天弄了一天的mysql数据库,就是被一个mysql数据库乱码的问题给缠住了.现在记录一下这个问题,虽然这个问题不是什么太大的事情,但还是记录一下. 问题是这样的: 1.先在mysql的安装文件当中, ...
- Visual C++ 8.0对象布局
哈哈,从M$ Visual C++ Team的Andy Rich那里又偷学到一招:VC8的隐含编译项/d1reportSingleClassLayout和/d1reportAllClassLayout ...