回顾复习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;
}
posted @ 2024-02-05 08:58  DrRatio  阅读(51)  评论(5编辑  收藏  举报