回顾复习x学习笔记
从头回顾(截至搜索)
#define fo(x,y,z) for(int (x)=(y);(x)<=(z);(x)++)
#define foo(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define fu(x,y,z) for(int (x)=(y);(x)>=(z);(x)--)
using namespace std;
inline int qr(){
char ch=getchar();int x=0,f=1;
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
return x*f;}
#define qr qr()
typedef long long ll;
0x 基础
0x01.快速幂
求a^b%p的值
前置要点:(ab)%p=(a%p)(b%p);(a^b)%p=[(a%p)*(a%p)]%p......
int power(int a,int b,int p)
{
int ans=1%p;
while(b)
{
if(b&1)ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
//若为long long直接改类型
0x02.前缀和
int a[N],s[N];//a为值 s为前缀和
memset(s,0,sizeof s);
fo(i,1,n)//a个数
s[i]=s[i-1]+a[i];
0x03.二分查找
(1)找>=x的数中最小的一个
while(l<r)
{
int mid=(l+r)/2;
if(a[mid]>=x)
l=mid;
else
r=mid-1;
}
return a[l];
等效于
ans=lower_bound(a+1,a+1+n,x)-a;
(2)找<=x中最大的一个
同上 改符号
0x04.二分答案
bool check(int x)
{
//依据题意判定答案范围并return
}
while(l<r)
{
int mid=(l+r)/2;
if(check(mid))//mid在答案范围内
l=mid;
else
r=mid-1;
}//这里取等以及l与r的取值均视情况而定
0x05.线性筛
int a[N],cnt,n,pri[N];
n=qr;
memset(a,0,sizeof ,a);
fo(i,2,n)
{
if(!a[i])
pri[++cnt]=i;
fo(j,1,cnt)
{
if(i*pri[j]>n)break;//不然会炸RE
a[i*pri[j]]=1;
if(!i%pri[j])break;
}
}
fo(i,1,cnt)
printf("%d\n",pri[i]);
0x06.高精度集合(负数未考虑)
(最喜欢的一集
const int Ratio=0;
const int N=10005;
char a[N],b[N];
int x;//进位
int lena,lenb,lenc;
int a1[N],b1[N],c1[N];
bool afu,bfu;
void wszlysdgjiajiajia()//加
{
lenc=max(lena,lenb);
fo(i,0,lenc-1)
{
c1[i]=a1[i]+b1[i]+x;
x=c1[i]/10;
c1[i]%=10;
}
if(x)
{
lenc++;
c1[lenc-1]=x;
}
}
void wszlysdgjianjian()//减
{
lenc=max(lena,lenb);
if(lena<lenb||(lena==lenb&&a1[lena-1]<b1[lenb-1]))//为让大减小 先比较
{
cout<<"-";
fo(i,0,lenc-1)
{
if(b1[i]-a1[i]<0)
{
b1[i+1]--;
b1[i]+=10;
}
c1[i]=b1[i]-a1[i];
}
while(!c1[lenc-1])--lenc;
}
else
{
fo(i,0,lenc-1)
{
if(a1[i]-b1[i]<0)
{
a1[i+1]--;
a1[i]+=10;
}
c1[i]=a1[i]-b1[i];
}
while(!c1[lenc-1])
{
if(lenc-1==0)break;
--lenc;
}
}
}
void wszlysdgcheng()//乘
{
if((lena==1&&a1[0]==0)||(lenb==1&&b1[0]==0))
{
c1[0] = 0;
lenc = 1;
return;
}
lenc=lena+lenb;
fo(i,0,lena-1)
{
fo(j,0,lenb-1)
{
c1[i+j]+=a1[i]*b1[j];
c1[i+j+1]+=c1[i+j]/10;
c1[i+j]%=10;
}
}
while(!c1[lenc-1])lenc--;
}
bool schssw(int a[],int b[],int len)
{
if(a[len]>0)return true;
fu(i,len-1,0)
if(a[i]>b[i])return true;
else if(a[i]<b[i])return false;
return true;
}
void wszlysdgchuchu()//除 顺位减
{
lenc=lena-lenb;
fu(i,lena-lenb,0)
{
while(schssw(a1+i,b1,lenb))
{
c1[i]++;
fo(j,0,lenb-1)
{
if(a1[i+j]<b1[j])
{
a1[i+j+1]--;
a1[i+j]+=10;
}
a1[i+j]-=b1[j];
}
}
}
while(c1[lenc]==0&&lenc>0)lenc--;
lenc++;
}
int main()
{
cin>>a>>b;
lena=strlen(a),lenb=strlen(b);
fo(i,0,lena-1)//倒序存储
a1[i]=a[lena-i-1]-'0';
fo(i,0,lenb-1)
b1[i]=b[lenb-i-1]-'0';
memset(c1,0,sizeof c1);
// wszlysdgchuchu();函数选择
fu(i,lenc-1,0)
cout<<c1[i];
return Ratio;
}
0x07.离散化与查询映射
int a[N],b[N],n,m=0;
void discrete()
{
sort(a+1,a+1+n);
fo(i,1,n)
if(i==1||a[i]!=a[i-1])
b[++m]=a[i];
}
int query(int x)
{
return lower_bound(b+1,b+1+m,x)-b;
}
0x08.逆序对+归并排序
定义:i<j且a[i]>a[j];
void merge(int l,int mid,int r)//a待排 b临时 cnt个数
{
int i=l,j=mid+1;
fo(k,l,r)
if(j>r||i<=mid&&a[i]<=a[j])
b[k]=a[i++];
else
b[k]=a[j++],cnt+=mid-i+1;
fo(k,l,r)
a[k]=b[k];
}
1x 搜索
1x01.dfs
图:
void dfs(int x)
{
v[x]=1;
for(int i=head[x];i;i=ne[i])
{
int y=to[i];
if(v[y])continue;
dfs(y);
}
}
树:
void dfs(int x)
{
a[++m]=x;
v[x]=1;
for(int i=head[i];i;i=ne[i])
{
int y=to[i];
if(v[y])continue;
dfs(y);
}
a[++m]=x;
}
1x02.bfs
图:
void bfs()
{
memset(d,0,sizeof d);
queue<int>q;
q.push(1);
d[1]=1;
while(q.size())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=ne[i])
{
int y=to[i];
if(d[y])continue;
d[y]=d[x]+1;
q.push(y);
}
}
}
1x03.拓扑排序
void add(int u,int v)
{
rm[++cnt].t=v;
rm[cnt].ne=head[u];
head[u]=cnt;
deg[v]++;
}
void topsort()
{
queue<int>q;
fo(i,1,n)
if(!deg[i])
q.push(i);
while(q.size())
{
int x=q.front();
q.pop();
a[++tot]=x;
for(int i=head[x];i;i=rm[i].ne)
{
int y=rm[i].t;
if(--deg[y]==0)
q.push(y);
}
}
}
int main()
{
n=qr,m=qr;
fo(i,1,m)
{
int x=qr,y=qr;
add(x,y);
}
topsort();
fo(i,1,tot)
printf("%d ",a[i]);
return Ratio;
}