模板库(不时更新。。感觉会咕咕咕)
FFT(快速傅里叶变换)
void FFT(complex<double>*p,int n,int tt){ complex<double>aa,bb,t0,t1; int i,j,k,m; for(i=0;i<n;i++){ for(j=0,k=i,m=n-1;m>0;j=(j<<1)|(k&1),k>>=1,m>>=1);//可以写在外面,用rev[]代替j,效率更高 if(i<j)swap(p[i],p[j]); } for(m=1;m<n;m<<=1){ aa=exp(complex<double>(0,tt*pi/(double)(m))); for(i=0;i<n;i+=(m<<1)){ bb=1; for(j=0;j<m;j++){ t0=p[i+j]; t1=p[i+j+m]*bb; p[i+j]=t0+t1; p[i+j+m]=t0-t1; bb*=aa; } } } if(tt==-1) { for(int i=0; i<n; i++) p[i]/=n; } }
BSGS算法
(map)求a^x=b(mod p)(p为质数)
ll ksm(ll x,ll y){ ll ans=1; while(y){ if(y&1)ans=(ans*x)%P; y>>=1; x=(x*x)%P; } return ans; } ll bsgs(ll a,ll b,ll p){ if(b==1)return 0; ll m=ceil(sqrt(p)); ll k=1; q.clear(); ll cc=ksm(a,m); ll ss=b; q[ss]=0; for(int i=1;i<=m;i++){ ss=ss*a%p; q[ss]=i; } ll o=1; for(int i=1;i<=m;i++){ o=o*cc%p; if(q[o]){ return i*m-q[o]+js; } } return -1; }
(Hash表)
ll ksm(ll x,ll y){ ll ans=1; while(y){ if(y&1)ans=(ans*x)%P; y>>=1; x=(x*x)%P; } return ans; } struct hashmap{ static const int mod=999917,maxn=50005; int _end[maxn],_next[maxn],_last[mod],state[maxn],val[maxn]; int o,top; void clear(){ o=0; while(top){ _last[state[top--]]=0; } } void add(int x,int y){ _end[++o]=y; _next[o]=_last[x]; _last[x]=o; val[o]=0x3f3f3f3f; } bool count(int y){ int x=y%mod; for(int j=_last[x];j;j=_next[j]){ if(y==_end[j])return 1; } return 0; } int& operator[](int y){ int x=y%mod; for(int j=_last[x];j;j=_next[j]){ if(y==_end[j]){ return val[j]; } } add(x,y); state[++top]=x; return val[o]; } }; hashmap Hash; ll exbsgs(ll a,ll b,ll p){ if(b==1)return 0; ll k=1; ll cc; ll m=ceil(sqrt(p)); Hash.clear(); cc=ksm(a,m); ll ss=b; Hash[ss]=0; for(int i=1;i<=m;i++){ ss=ss*a%p; Hash[ss]=i; } for(int i=1;i<=m;i++){ k=k*cc%p; if(Hash.count(k)){ return i*m-Hash[k]; } } return -1; }
Catalan数
void cg(int k,int tt){ int cc=0; for(int i=100;i>=0;i--){ cc += a[k-1][i]*tt; a[k][i]=cc%BASE; cc/=BASE; } } void ch(int k,int tt){ int cc=0; for(int i=0;i<=100;i++){ cc=cc*BASE+a[k][i]; a[k][i]=cc/tt; cc%=tt; } } int main(){ memset(a,0,sizeof(a)); a[0][100] = 1; for(int i = 1;i <= 100;i++){ cg(i,4*i-2); ch(i,i+1); } int n; scanf("%d",&n); while(n!=-1){ int pos=-1; for(int i=0;i<=100;i++){ if(a[n][i]){ pos=i; break; } } printf("%d",a[n][pos]); for(int i=pos+1;i<=100;i++){ printf("%04d",a[n][i]); } printf("\n"); scanf("%d",&n); } return 0; }
后缀自动机
ll push(ll x){ mx[++tot]=x; return tot; } struct node{ void init(){ memset(son,0,sizeof(son)); memset(pre,0,sizeof(pre)); last=tot=root=1; } void ins(ll t){ ll p=last,np=push(mx[p]+1); si[np]=tt[np]=1; while(p&&!son[p][t]){ son[p][t]=np; p=pre[p]; } if(!p)pre[np]=root; else{ ll q=son[p][t]; if(mx[q]==mx[p]+1)pre[np]=q; else{ ll nq=push(mx[p]+1); memcpy(son[nq],son[q],sizeof(son[q])); pre[nq]=pre[q]; pre[q]=pre[np]=nq; while(p&&son[p][t]==q){ son[p][t]=nq; p=pre[p]; } } } last=np; } }sam;
SAM的拓扑排序
ll push(ll x){
mx[++tot]=x;
return tot;
}
struct node{
void init(){
memset(pre,0,sizeof(pre));
last=root=tot=1;
}
void ins(ll t){
ll p=last,np=push(mx[p]+1);
v1[np]=1;
while(p&&!son[p][t]){
son[p][t]=np;
p=pre[p];
}
if(!p){
pre[np]=root;
++dd[root];
}
else{
ll q=son[p][t];
if(mx[q]==mx[p]+1){
pre[np]=q;
++dd[q];
}
else{
ll nq=push(mx[p]+1);
son[nq]=son[q];
pre[nq]=pre[q];
pre[q]=pre[np]=nq;
dd[nq]+=2;/*****/
while(p&&son[p][t]==q){
son[p][t]=nq;
p=pre[p];
}
}
}
last=np;
}
void topsortr(){
queue<ll>Q;
for(ll i=1;i<=tot;++i) {
if(!dd[i])Q.push(i);
}
ll ans=0;
while(Q.size()){
ll tt=Q.front();
Q.pop();
v1[pre[tt]]+=v1[tt];
--dd[pre[tt]];
if(!dd[pre[tt]])Q.push(pre[tt]);
}
}
}sam;
树状数组(加减以及求答案操作)
void add(int x,int d){ if(!x)return; while(x<=N){ c[x]+=d; x+=lowbit(x); } } int gs(int x){ if(!x)return 0; int anss=0; while(x){ anss+=c[x]; x-=lowbit(x); } return anss; }
二逼平衡树(线段树套splay)
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#define maxn 1000005
#define inf 0x3f3f3f3f
using namespace std;
int N,M;
int v[maxn],fz[maxn],ch[maxn][2],si[maxn],cnt[maxn];
int root[maxn],pp[maxn];
int Pre,Suc;
int tot;
int maxx;
void update(int x){
si[x]=si[ch[x][0]]+si[ch[x][1]]+cnt[x];
}
void xz(int x,int &rt){
int y=fz[x],z=fz[y];
bool t=(ch[y][0]==x);
if(z)ch[z][ch[z][1]==y]=x;
else rt=x;
fz[x]=z;
fz[y]=x;
fz[ch[x][t]]=y;
ch[y][t^1]=ch[x][t];
ch[x][t]=y;
update(y);
update(x);
}
void splay(int x,int &rt){
while(x!=rt){
int y=fz[x],z=fz[y];
if(y==rt){
xz(x,rt);
return;
}
if((ch[y][0]==x)^(ch[z][0]==y))xz(x,rt);
else xz(y,rt);
xz(x,rt);
}
}
void ins(int &p,int x,int fa,int id){
if(!p){
p=++tot;
v[p]=x;
fz[p]=fa;
cnt[p]=si[p]=1;
splay(p,root[id]);
return;
}
if(v[p]==x){
cnt[p]++;
si[p]++;
splay(p,root[id]);
}
else{
if(x<v[p])ins(ch[p][0],x,p,id);
else ins(ch[p][1],x,p,id);
}
}
int find(int p,int x){
if(v[p]==x)return p;
if(x<v[p])return find(ch[p][0],x);
else return find(ch[p][1],x);
}
void del(int x,int id){
int p=find(root[id],x);
splay(p,root[id]);
if(cnt[p]>1){
cnt[p]--;
si[p]--;
return;
}
if((!ch[p][0])||(!ch[p][1])){
root[id]=ch[p][0]+ch[p][1];
fz[root[id]]=0;
return;
}
int pre=ch[p][0],suc=ch[p][1];
while(ch[pre][1])pre=ch[pre][1];
while(ch[suc][0])suc=ch[suc][0];
splay(pre,root[id]);
splay(suc,ch[root[id]][1]);
ch[suc][0]=0;
update(suc);
update(pre);
}
void inss(int p,int l,int r,int id,int k){
ins(root[p],k,0,p);
if(l==r)return;
int mid=l+r>>1;
if(id<=mid)inss(p<<1,l,mid,id,k);
else inss(p<<1|1,mid+1,r,id,k);
}
int cx1(int p,int x){
if(!p)return 0;
if(x<v[p])return cx1(ch[p][0],x);
else{
if(x==v[p])return si[ch[p][0]];
else return si[ch[p][0]]+cnt[p]+cx1(ch[p][1],x);
}
}
int sl1(int p,int l,int r,int L,int R,int x){
if(L<=l&&r<=R)return cx1(root[p],x);
int mid=l+r>>1;
int anss=0;
if(L<=mid)anss+=sl1(p<<1,l,mid,L,R,x);
if(mid+1<=R)anss+=sl1(p<<1|1,mid+1,r,L,R,x);
return anss;
}
int sl2(int L,int R,int k){
int l=1,r=maxx;
int ans=0;
while(l<=r){
int mid=l+r>>1;
if(sl1(1,1,N,L,R,mid)>=k)r=mid-1;
else{
l=mid+1;
ans=mid;
}
}
return ans;
}
void sl3(int p,int l,int r,int pos,int x){
if(l==r){
v[root[p]]=x;
return;
}
del(pp[pos],p);
ins(root[p],x,0,p);
int mid=l+r>>1;
if(pos<=mid)sl3(p<<1,l,mid,pos,x);
else sl3(p<<1|1,mid+1,r,pos,x);
}
void cx4(int p,int x){
if(v[p]<x){
Pre=max(Pre,v[p]);
if(ch[p][1])cx4(ch[p][1],x);
}
else{
if(ch[p][0])cx4(ch[p][0],x);
}
}
void sl4(int p,int l,int r,int L,int R,int x){
if(L<=l&&r<=R){
cx4(root[p],x);
return;
}
int mid=l+r>>1;
if(L<=mid)sl4(p<<1,l,mid,L,R,x);
if(mid+1<=R)sl4(p<<1|1,mid+1,r,L,R,x);
}
void cx5(int p,int x){
if(v[p]>x){
Suc=min(Suc,v[p]);
if(ch[p][0])cx5(ch[p][0],x);
}
else{
if(ch[p][1])cx5(ch[p][1],x);
}
}
void sl5(int p,int l,int r,int L,int R,int x){
if(L<=l&&r<=R){
cx5(root[p],x);
return;
}
int mid=l+r>>1;
if(L<=mid)sl5(p<<1,l,mid,L,R,x);
if(mid+1<=R)sl5(p<<1|1,mid+1,r,L,R,x);
}
int main(){
scanf("%d%d",&N,&M);
for(int i=1;i<=N;++i){
scanf("%d",&pp[i]);
inss(1,1,N,i,pp[i]);
maxx=max(maxx,pp[i]);
}
int ty;
int pos,l,r,k;
while(M--){
scanf("%d",&ty);
if(ty==1){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",sl1(1,1,N,l,r,k)+1);
continue;
}
if(ty==2){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",sl2(l,r,k));
continue;
}
if(ty==3){
scanf("%d%d",&pos,&k);
sl3(1,1,N,pos,k);
maxx=max(maxx,k);
pp[pos]=k;
continue;
}
if(ty==4){
scanf("%d%d%d",&l,&r,&k);
Pre=-inf;
sl4(1,1,N,l,r,k);
printf("%d\n",Pre);
continue;
}
if(ty==5){
scanf("%d%d%d",&l,&r,&k);
Suc=inf;
sl5(1,1,N,l,r,k);
printf("%d\n",Suc);
}
}
return 0;
}
线性基(合并)
struct xxj{
ll v[65];
void add(ll x){
for(int i=61;i>=0;--i){
if(x&(1ll<<i)){
if(!v[i]){
v[i]=x;
break;
}
x^=v[i];
}
}
}
ll cx(){
ll anss=0;
for(int i=61;i>=0;--i){
anss=max(anss,anss^v[i]);
}
return anss;
}
}g[20005][20];
xxj oh_yeah(xxj a,xxj b){
xxj xxx=a;
for(int i=61;i>=0;--i){
if(b.v[i]){
xxx.add(b.v[i]);
}
}
return xxx;
}
伪四维偏序(三维偏序)【[Ahoi2008]Rectangle 矩形藏宝地】
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<algorithm>
#define ll long long
#define maxn 200005
#define lowbit(x) (x&(-x))
using namespace std;
int N;
int ans[maxn<<1];
struct node{
int x1,y1,x2,y2;
int id;
bool fg;
}p[maxn<<1],pp[maxn<<1];
int lsh[maxn<<1];
bool cmp(node a,node b){
return a.x1<b.x1;
}
int c[maxn<<1];
int maxx;
void add(int x,int d){
while(x<=maxx){
c[x]=max(c[x],d);
x+=lowbit(x);
}
}
void xxx(int x){
while(x<=maxx){
c[x]=0;
x+=lowbit(x);
}
}
int gs(int x){
int anss=0;
while(x){
anss=max(anss,c[x]);
x-=lowbit(x);
}
return anss;
}
void solve(int l,int r){
if(l==r)return;
int mid=l+r>>1;
solve(l,mid);
solve(mid+1,r);
int i=l,j,tt=l;
for(j=mid+1;j<=r;++j){
while(p[i].y1<=p[j].y1&&i<=mid){
add(maxx-p[i].x2,p[i].y2);
pp[tt++]=p[i];
i++;
}
pp[tt++]=p[j];
if(gs(maxx-p[j].x2)>p[j].y2){
ans[p[j].id]=1;
}
}
while(i<=mid){
pp[tt++]=p[i++];
}
for(i=l;i<=mid;++i){
xxx(maxx-p[i].x2);
}
for(int i=l;i<=r;++i){
p[i]=pp[i];
}
}
int main(){
scanf("%d",&N);
for(int i=1;i<=N;++i){
scanf("%d%d%d%d",&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2);
lsh[i]=p[i].x2;
p[i].id=i;
}
maxx=N+1;
sort(lsh+1,lsh+1+N);
for(int i=1;i<=N;++i){
p[i].x2=lower_bound(lsh+1,lsh+1+N,p[i].x2)-lsh;
}
sort(p+1,p+1+N,cmp);
solve(1,N);
int anss=0;
for(int i=1;i<=N;++i){
if(ans[i])anss++;
}
printf("%d",anss);
return 0;
}

浙公网安备 33010602011771号