SCP(大雾)复习板子?

复习一下各种板子?

  • 树状数组

其实忘得差不多了,只会lowbit了qaq

树状数组一的话就正常搞

#include<cstdio>
#define sev en
using namespace std;

#define N 500010

int n,m;
int tree[N];

int lowbit(int x) {
    return x & (-x);
}

void add(int x,int k) {
    while(x <= n) {
        tree[x] += k;
        x += lowbit(x);
    }
}

int query(int x) {
    int ans = 0;
    while(x) {
        ans += tree[x];
        x -= lowbit(x);
    }
    return ans;
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++) {
        int x;
        scanf("%d",&x);
        add(i,x);
    }
    for(int i = 1; i <= m; i++) {
        int op,x,k;
        scanf("%d%d%d",&op,&x,&k);
        if(op == 1)
            add(x,k);
        else
            printf("%d
",query(k) - query(x - 1));
    }
    return 0;
}
BIT1

树状数组二用到了差分

反正是忘了嘤

#include<cstdio>
#define sev en
using namespace std;

#define N 500010

int n,m;
int tree[N];

int lowbit(int x) {
    return x & (-x);
}

void add(int x,int k) {
    while(x <= n) {
        tree[x] += k;
        x += lowbit(x);
    }
}

int query(int x) {
    int ans = 0;
    while(x) {
        ans += tree[x];
        x -= lowbit(x);
    }
    return ans;
}

int main() {
    scanf("%d%d",&n,&m);
    int st = 0;
    for(int i = 1; i <= n; i++) {
        int x;
        scanf("%d",&x);
        add(i,x - st);
        st = x;
    }
    for(int i = 1; i <= m; i++) {
        int op,x,y,k;
        scanf("%d",&op);
        if(op == 1) {
            scanf("%d%d%d",&x,&y,&k);
            add(x,k);
            add(y + 1,-k);
        } else {
            scanf("%d",&x);
            printf("%d
",query(x));
        }
    }
    return 0;
}
BIT2
  • 并查集 

第一遍居然写跪了

我码之前还表示这要是不会就告辞了 脸疼

无论如何反正码风比以前好看了

#include<cstdio>
#define sev en
using namespace std;

#define N 10010

int n,m;
int fa[N];

int get(int x) {
    if(fa[x] == x)
        return x;
    return fa[x] = get(fa[x]);
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++)
        fa[i] = i;
    for(int i = 1; i <= m; i++) {
        int op,x,y;
        scanf("%d%d%d",&op,&x,&y);
        if(op == 1)
            fa[get(x)] = get(y);
        else {
            if(get(x) == get(y))
                printf("Y
");
            else
                printf("N
");
        }
    }
    return 0;
}
Union Find
  • 线段树

前一阵子刚码过一遍

但仍然出了一些问题

比如需要记住lazy乘16 询问的时候往下传是+= sum也是w

说实在的

现在心情有点差 特别差那种 有点想离开

真是无趣啊 千篇一律的人生 碌碌无为的时光 蝇营狗苟的未来 浑浑噩噩的打转

真烦 

#include<cstdio>
#define sev en
using namespace std;

#define N 100010

int n,m;
long long sum[N << 2],lazy[N << 4];
int l[N << 2],r[N << 2];

void build(int now,int L,int R) {
    lazy[now] = 0;
    l[now] = L,r[now] = R;
    if(L == R) {
        scanf("%lld",&sum[now]);
        return ;
    }
    int mid = (L + R) >> 1;
    build(now << 1,L,mid);
    build(now << 1 | 1,mid + 1,R);
    sum[now] = sum[now << 1] + sum[now << 1 | 1];
}

void modify(int now,int L,int R,int k) {
    if(L == l[now] && R == r[now]) {
        lazy[now] += k;
        return ;
    }
    sum[now] += (R - L + 1) * k;
    int mid = (l[now] + r[now]) >> 1;
    if(mid >= R)
        modify(now << 1,L,R,k);
    else if(L > mid)
        modify(now << 1 | 1,L,R,k);
    else {
        modify(now << 1,L,mid,k);
        modify(now << 1 | 1,mid + 1,R,k);
    }
    return ;
}

long long query(int now,int L,int R) {
    sum[now] += (r[now] - l[now] + 1) * lazy[now];
    lazy[now << 1] += lazy[now],lazy[now << 1 | 1] += lazy[now];
    lazy[now] = 0;
    if(L == l[now] && R == r[now])
        return sum[now];
    int mid = (l[now] + r[now]) >> 1;
    if(mid >= R)
        return query(now << 1,L,R);
    else if(L > mid)
        return query(now << 1 | 1,L,R);
    else
        return query(now << 1,L,mid) + query(now << 1 | 1,mid + 1,R);
}

int main() {
    scanf("%d%d",&n,&m);
    build(1,1,n);
    for(int i = 1; i <= m; i++) {
        int op,x,y,k;
        scanf("%d",&op);
        if(op == 1) {
            scanf("%d%d%d",&x,&y,&k);
            modify(1,x,y,k);
        } else {
            scanf("%d%d",&x,&y);
            printf("%lld
",query(1,x,y));
        }
    }
    return 0;
}
segment tree 1
  •  最短路-dijkstra

 唔,虽然有点问题 但码的还算可以

为了优化加的vis别忘了就好w

没加的时候标准版过不了嘤

心情不要太差哦

你看 你的私信里有一个明亮的1呢

#include<cstdio>
#include<queue>
#define sev en
using namespace std;

#define N 500010
#define INF 2147483647

int n,m,s,cnt;
int to[N],nxt[N],w[N],head[N];
int dis[N],vis[N];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;

void add(int x,int y,int z){
  to[++cnt] = y;
  w[cnt] = z;
  nxt[cnt] = head[x];
  head[x] = cnt;
}

int main(){
  scanf("%d%d%d",&n,&m,&s);
  for(int i = 1;i <= m;i++){
    int x,y,z;
    scanf("%d%d%d",&x,&y,&z);
    add(x,y,z);
  }
  for(int i = 1;i <= n;i++)
    dis[i] = INF;
  dis[s] = 0;
  q.push(make_pair(0,s));
  while(!q.empty()){
    int x = q.top().second;
    q.pop();
    if(vis[x])
    continue;
    vis[x] = 1;
    for(int i = head[x];i;i = nxt[i]){
      int v = to[i];
      if(dis[x] != INF && dis[v] > dis[x] + w[i]){
    dis[v] = dis[x] + w[i];
    q.push(make_pair(dis[v],v));
      }
    }
  }
  for(int i = 1;i <= n;i++)
    printf("%d ",dis[i]);
  return 0;
}
  
dijkstra
  •  最小生成树-kruskal

 难得的一边写过的代码

有点困有点累好闷啊要死了

#include<cstdio>
#include<algorithm>
#define sev en
using namespace std;

#define M 200010
#define N 5010

int n,m;
struct EDGE{
  int x,y,w;
  bool operator <(const EDGE &a)const{
    return w < a.w;
  }
}e[M << 1];
int fa[N],ans,num;

int get(int x){
  if(fa[x] == x)
    return x;
  return fa[x] = get(fa[x]);
}

void kruskal(){
  for(int i = 1;i <= m;i++){
    int l = get(e[i].x),r = get(e[i].y);
    if(l != r){
      fa[l] = r;
      ans += e[i].w;
      num++;
    }
  }
}

int main(){
  scanf("%d%d",&n,&m);
  for(int i = 1;i <= m;i++)
    scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
  sort(e + 1,e + m + 1);
  for(int i = 1;i <= n;i++)
    fa[i] = i;
  kruskal();
  if(num < n - 1)
    printf("orz");
  else
    printf("%d",ans);
  return 0;
}
kruskal
  •  逆序对

 重新写了一下逆序对 代码跟之前的有一点点不同

大概码风不太一样?更好了?更符合我现在的审美吧

树状数组

#include<cstdio>
#include<algorithm>
#define sev en
using namespace std;

#define N 500010

int n;
int a[N],b[N];
long long ans,tree[N];

int lowbit(int x){
    return x & (-x);
}

void add(int x){
    while(x <= n){
        tree[x]++;
        x += lowbit(x);
    }
}

long long query(int x){
    long long ret = 0;
    while(x){
        ret += tree[x];
        x -= lowbit(x);
    }
    return ret;
}

int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) {
        scanf("%d",&a[i]);
        b[i] = a[i];
    }
    sort(a + 1,a + n + 1);
    int num = unique(a + 1,a + n + 1) - a - 1;
    for(int i = 1; i <= n; i++)
        b[i] = lower_bound(a + 1,a + num + 1,b[i]) - a;
    for(int i = n; i >= 1; i--) {
        add(b[i]);
        ans += query(b[i] - 1);
    }
    printf("%lld",ans);
    return 0;
}
count inversion 1

归并排序

#include<cstdio>
#define sev en
using namespace std;

#define N 500010

int n;
int a[N],q[N];
long long ans;

void merge(int l,int r) {
    if(l == r)
        return ;
    int mid = (l + r) >> 1;
    merge(l,mid);
    merge(mid + 1,r);
    int i = l,j = mid + 1,k = l;
    while(i <= mid && j <= r) {
        if(a[i] <= a[j])
            q[k++] = a[i++];
        else {
            q[k++] = a[j++];
            ans += (mid - i + 1);
        }
    }
    while(i <= mid)
        q[k++] = a[i++];
    while(j <= r)
        q[k++] = a[j++];
    for(int i = l; i <= r; i++)
        a[i] = q[i];
}

int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; i++)
        scanf("%d",&a[i]);
    merge(1,n);
    printf("%lld",ans);
    return 0;
}
count inversion 2
  •  素数筛法

 先写了个素数个数emmm

纯筛 没用啥筛法 硬刚就好

#include<cstdio>
#include<cmath>
#define sev en
using namespace std;

const int N = 1e8 + 10;

bool f[N];

int main() {
    int n;
    scanf("%d",&n);
    int ans = n - 1;
    for(int i = 2; i <= sqrt(n); i++) {
        if(f[i])
            continue;
        for(int j = i * 2; j <=n; j += i)
            if(!f[j])
                f[j] = 1,ans--;
    }
    printf("%d",ans);
    return 0;
}
prime 1

然后写了个线性筛素数

欧拉筛

一开始写prime数组写到判断是否素数后面了 所以是bool类型 de了5分钟 气死

emmmm也不清楚到底懂得彻不彻底 

希望能记住吧~

#include<cstdio>
#include<cstring>
#define sev en
using namespace std;

const int N = 1e7 + 10;

int n,m;
bool f[N];
int prime[N];
int num;

void Prime() {
    memset(f,true,sizeof(f));
    f[0] = f[1] = 0;
    for(int i = 2; i <= n; i++) {
        if(f[i]) {
            prime[num++] = i;
        }
        for(int j = 0; j < num && i * prime[j] <= n; j++) {
            f[i * prime[j]] = 0;
            if(!(i % prime[j]))
                break;
        }
    }
    return ;
}

int main() {
    scanf("%d%d",&n,&m);
    Prime();
    while(m--) {
        int x;
        scanf("%d",&x);
        if(f[x])
            printf("Yes
");
        else
            printf("No
");
    }
    return 0;
}
prime 2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/sevenyuanluo/p/11837676.html