1.数据结构
1.1 并查集
int find(int x){
if(f[x]==x) return x;
return f[x]=find(f[x]);
}
1.2 线段树
1.2.1 线段树(区间加法)
struct tree{ //树结构体
int l,r;
unsigned long long sum;
unsigned long long add;
}t[maxn*4];
void build(int p,int l,int r){ //建树
t[p].l=l,t[p].r=r;
if(l==r){
t[p].sum=a[l];
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
void spread(int p){ //打标记
if(t[p].add){
t[p*2].sum+=(t[p*2].r-t[p*2].l+1)*t[p].add;
t[p*2+1].sum+=(t[p*2+1].r-t[p*2+1].l+1)*t[p].add;
t[p*2].add+=t[p].add;
t[p*2+1].add+=t[p].add;
t[p].add=0;
}
}
void change(int p,int l,int r,unsigned long long v){ //更新
if(l<=t[p].l&&r>=t[p].r){
t[p].sum+=(t[p].r-t[p].l+1)*v;
t[p].add+=v;
return;
}
spread(p);
int mid=(t[p].l+t[p].r)/2;
if(l<=mid) change(p*2,l,r,v);
if(r>mid) change(p*2+1,l,r,v);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
unsigned long long ask(int p,int l,int r){ //区间查询
if(l<=t[p].l&&r>=t[p].r) return t[p].sum;
spread(p);
int mid=(t[p].l+t[p].r)/2;
unsigned long long val=0;
if(l<=mid) val+=ask(p*2,l,r);
if(r>mid) val+=ask(p*2+1,l,r);
return val;
}
1.2.2 线段树(区间乘法)
struct tree{
int l,r;
long long sum;
long long mu;
long long add;
}t[maxn*4];
long long a[maxn];
long long n,m,x,y,k,p,mod;
inline void build(long long p,long long l,long long r){
t[p].l=l,t[p].r=r,t[p].mu=1;
if(l==r){
t[p].sum=a[l]%mod;
return;
}
long long mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
inline void spread(long long p){
t[p*2].sum=(t[p].mu*t[p*2].sum+((t[p*2].r-t[p*2].l+1)*t[p].add)%mod)%mod;
t[p*2+1].sum=(t[p].mu*t[p*2+1].sum+((t[p*2+1].r-t[p*2+1].l+1)*t[p].add)%mod)%mod;
t[p*2].mu=(t[p*2].mu*t[p].mu)%mod;
t[p*2+1].mu=(t[p*2+1].mu*t[p].mu)%mod;
t[p*2].add=(t[p*2].add*t[p].mu+t[p].add)%mod;
t[p*2+1].add=(t[p*2+1].add*t[p].mu+t[p].add)%mod;
t[p].mu=1,t[p].add=0;
}
inline void change1(long long p,long long l,long long r,long long w){
if(l<=t[p].l&&r>=t[p].r){
t[p].add=(t[p].add+w)%mod;
t[p].sum=(t[p].sum+(t[p].r-t[p].l+1)*w)%mod;
return;
}
spread(p);
t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
long long mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change1(p*2,l,r,w);
if(r>mid) change1(p*2+1,l,r,w);
t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
}
inline void change2(long long p,long long l,long long r,long long w){
if(l<=t[p].l&&r>=t[p].r){
t[p].add=(t[p].add*w)%mod;
t[p].mu=(t[p].mu*w)%mod;
t[p].sum=(t[p].sum*w)%mod;
return;
}
spread(p);
long long mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change2(p*2,l,r,w);
if(r>mid) change2(p*2+1,l,r,w);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
inline long long ask(long long p,long long l,long long r){
if(l<=t[p].l&&r>=t[p].r) return t[p].sum%mod;
spread(p);
long long mid=(t[p].l+t[p].r)>>1;
long long val=0;
if(l<=mid) val+=ask(p*2,l,r),val%=mod;
if(r>mid) val+=ask(p*2+1,l,r),val%=mod;
return val%mod;
}
1.3 树状数组(暂无)
1.4 树链剖分(暂无)
1.5 莫队
const int maxn=1000005;
int cnt[maxn],a[maxn],belong[maxn];
int n,m,now,size,bnum;
int ans[maxn];
struct data{
int l,r,id;
}q[maxn];
int cmp(data a,data b){
return (belong[a.l]^belong[b.l])?belong[a.l]<belong[b.l]:((belong[a.l]&1)?a.r<b.r:a.r>b.r);
}
int main(){
n=read();
size=sqrt(n);
bnum=ceil((double)n/size);
for(int i=1;i<=bnum;++i)
for(int j=(i-1)*size+1;j<=i*size;++j) belong[j]=i;
for(int i=1;i<=n;++i) a[i]=read();
m=read();
for(int i=1;i<=m;++i){
q[i].l=read(),q[i].r=read();
q[i].id=i;
}
int l=l,r=0;
sort(q+1,q+m+1,cmp);
for(int i=1;i<=m;++i){
int ql=q[i].l,qr=q[i].r;
while(l>ql) l--,now+=!cnt[a[l]],cnt[a[l]]++;
while(r<qr) r++,now+=!cnt[a[r]],cnt[a[r]]++;
while(l<ql) cnt[a[l]]--,now-=!cnt[a[l]],l++;
while(r>qr) cnt[a[r]]--,now-=!cnt[a[r]],r--;
ans[q[i].id]=now;
}
for(int i=1;i<=m;++i) print(ans[i]),putchar('\n');
return 0;
}
2.图论
2.1 Kruskal(最小生成树)
struct data{
int u,v,w;
}e[500005];
bool cmp(data a,data b){
return a.w<b.w;
}
int find(int x){
if(x==f[x]) return x;
return f[x]=find(f[x]);
}
void kruskal(){
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;++i){
int eu=find(e[i].u),ev=find(e[i].v);
if(eu==ev) continue;
ans+=e[i].w;
f[ev]=eu;
if(++cnt==n-1) break;
}
}
2.2 Prim(最小生成树)
struct node{
int next,to,w;
}e[5000005];
int dis[5005],head[5005],tot,n,ans,cnt,now=1;
bool vis[5005]={0,1};
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt;
}
int prim(){
for(register int i=2;i<=n;++i){
dis[i]=maxn;
}
for(register int i=head[1];i!=-1;i=e[i].next){
dis[e[i].to]=min(dis[e[i].to],e[i].w);
}
while(++tot<n){
int minn=maxn;
for(register int i=1;i<=n;++i){
if(!vis[i]&&dis[i]<minn){
minn=dis[i];
now=i;
}
}
vis[now]=1;
ans+=minn;
for(register int i=head[now];i!=-1;i=e[i].next){
if(!vis[e[i].to]&&dis[e[i].to]>e[i].w)
dis[e[i].to]=e[i].w;
}
}
return ans;
}
2.3 Floyd(最短路(无法处理负权边))
void floyd(){ //复杂度n^3
for(int k=1;k<=n;++k){
for(int i=1;i<=n;++i){
if(i==k||a[i][k]==inf) continue;
for(int j=1;j<=n;++j)
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
}
}
}
2.4 Dijkstra(最短路(可处理负权边))
struct data{
int w,to,next;
}e[500005];
int cnt,n,m,s;
int head[maxn],vis[maxn],dis[maxn];
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt;
}
struct node{
int w,now;
inline bool operator < (const node &x) const
{
return w>x.w;
}
};
priority_queue<node>q;
void dijkstra(){ //n*logn
for(int i=1;i<=n;++i) dis[i]=inf;
dis[s]=0;
q.push((node){0,s});
while(!q.empty()){
node x=q.top();
q.pop();
int u=x.now;
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
q.push((node){dis[v],v});
}
}
}
}
2.5 LCA(最近公共祖先)(暂无)
2.6 拓补排序(暂无)
3.字符串
3.1 字符串hash
//单hash
const unsigned long long base=131;
const unsigned long long mod=212370440130137957ll;
int n;
unsigned long long a[10005],ans=1;
char c[10005];
unsigned long long hash1(char c[]){
int len=strlen(c);
unsigned long long ans=0;
for(int i=0;i<len;++i){
ans=(ans*base+c[i])%mod;
}
return ans;
}
3.2 KMP(暂无)
3.3 mannachar(暂无)
4.杂项
4.1 快读
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
4.2 快写
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9){
print(x/10);
}
putchar(x%10+'0');
}
4.3 减少cin、cout耗费时间
std::ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
4.4 欧拉筛
void ols(int n){
memset(vis,1,sizeof(vis));
vis[1]=0;
for(register int i=2;i<=n;++i){
if(vis[i]==1) ss[++cnt]=i;
for(register int j=1;j<=cnt&&i*ss[j]<=n;++j){
vis[i*ss[j]]=0;
if(i%ss[j]==0) break;
}
}
}
4.5 最大公约数
int gcd(int a,int b){
return b?(gcd(b,a%b)):a;
}
4.6 int128
void scan(__int128 &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
x*=f;
}
void _print(__int128 x){
if(x>9) _print(x/10);
putchar(x%10+'0');
}
void print(__int128 x){
if(x<0) x=-x,putchar('-');
_print(x);
}
4.7 快速幂+龟速乘
long long gsc(long long a,long long b,long long m){
long long f=1,sum=0;
if(a<0) f=-1,a=-a;
if(b<0) f*=-1,b=-b;
while(a){
if(a&1){
sum=(sum+b)%m;
}
b=b*2%m;
a>>=1;
}
return sum*f%m;
}
long long ksm(long long x,long long n,long long m){
long long ans=1;
while(n){
if(n&1){
ans=gsc(ans,x,m);
n--;
}
x=gsc(x,x,m);
n/=2;
}
return ans%m;
}
AFO了,有缘再更……