首页 > 代码库 > 【不定期更新】noip复习(或许有误请指正)
【不定期更新】noip复习(或许有误请指正)
一、基本算法
2.二分查找
void find(int l,int r){ if (l>r || a[l]>x || a[r]<x) return; int mid = (l+r) >> 1; if (a[mid] == x){ if (mid < pos)pos=mid; if (a[mid-1] == x) find(l, mid-1); if (a[mid+1] == x) find(mid+1, r); return; } if (x > a[mid]) find(mid+1, r); else find(l, mid-1);}
3.判断素数
bool is_prime(int x){ if (x <= 1) return 0; for (int i = 2; i <= floor(sqrt(x)+0.5); i++){ if (x % i == 0) return 0; } return 1;}
4.线性筛素数
for (int i = 1; i <= n; i++){ if (!flag[i]) ans[tot++]=i; for (int j=0 ; j < tot && i*ans[j] <= n ;j++){ flag[i * ans[j]]=1; if (i % ans[j]==0) break; }}
5.归并排序(求逆序对)
void merge(int a, int m, int b, int n){ int i = a, j = b, k = a; while (i <= m && j <= n){ if (s[i] <= s[j]) t[k++] = s[i++]; else{ t[k++] = s[j++]; ans += m-i+1; } } while (i <= m) t[k++] = s[i++]; while (j <= n) t[k++] = s[j++]; for (int i=a; i<=n; i++) s[i] = t[i];}void mergesort(int a, int b){ if (a == b) return; int mid = (a+b) / 2; mergesort(a, mid); mergesort(mid+1, b); merge(a, mid, mid+1, b);}//ans为逆序对个数
二、数据结构
1.(小根)二叉堆
void shift_down(int p){ int mp = 2*p; while (mp <= n){ if (p*2 == n || a[p*2] < a[p*2+1]) mp=2*p; else mp=2*p+1; if (a[mp] < a[p]) swap(a[mp], a[p]); else break; p=mp; mp=2*p; }}void shift_up(int p){ while (p > 1 && a[p] < a[p/2]){ swap(a[p], a[p/2]); p /= 2; }}
2.并查集
int find(int x){return (x==f[x]) ? x : f[x] = find(f[x]); }int union(int a, int b){ int x=find(a), y=find(b); if (rank[a]<rank[b]) father[a]=b; else{ father[b]=a; if (rank[b]==rank[a])++rank[b]; }}
3.线段树
struct node{int l, r, cover; };void bulid_tree(int p, int s, int t){ node &a=tree[p]; a.l = s; a.r = t; if (a.l == a.r) return; int mid = (s+t) >> 1; bulid_tree(p*2, s, mid); bulid_tree(p*2+1, mid+1, t);}void insert(int p, int s, int t){ node &a = tree[p]; if (a.l == s && a.r == t) {a.cover++; return;} if (a.l == a.r) return; //不能写成s==t int mid = (a.l+a.r) >> 1; if (t <= mid) insert(p*2, s, t); else if (s > mid) insert(p*2+1, s, t); else{ insert(p*2, s, mid); insert(p*2+1, mid+1, t); }} int count(int p, int x){ node &a = tree[p]; if (a.l == x && a.r == x) return a.cover; int mid = (a.l+a.r) >> 1,t = 0; if (x <= mid) t = count(p*2, x); else t = count(p*2+1, x); return (a.cover + t);}
4.树状数组
#define lowbit(i) i&(-i)void update(int x, int y, int d){ x++; y++; for (int i=x; i<INF; i+=lowbit(i)) for (int j=y; j<INF; j += lowbit(j)) c[i][j] += d;} int count(int x,int y){ int ans=0; x++; y++; for (int i=x;i;i-=lowbit(i)) for (int j=y;j;j-=lowbit(j)) ans+=c[i][j]; return ans;}
5.字典树(Trie)
struct Trie{ int tot,root,child[max_node][charset]; bool flag[max_node]; Trie() { memset(child[1],0,sizeof(child[1])); flag[1]=0; root=tot=1; }void insert(const char *str) //刚传进来的时候*str表示的是str[0] str表示整个字符数组 { int *cur=&root; for (const char *p=str;*p;++p) //p刚开始指向str[0] ++p表示取str的下一位 若为‘\0‘则退出 { cur=&child[*cur][*p-‘a‘]; if (*cur==0) { *cur=++tot; memset(child[tot],0,sizeof(child[tot])); flag[tot]=0; } } flag[*cur]=1; } bool query(const char *str) { int *cur=&root; for (const char *p=str;*p && *cur;++p) cur=&child[*cur][*p-‘a‘]; return (*cur && flag[*cur]); }};
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。