• 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

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    利用sklearn训练LDA主题模型及调参详解
    关联规则挖掘:Apriori算法(基于Groceries数据集)
    极大连通子图与极小连通子图
    TCP协议“三次握手”与“四次挥手”详解(下)
    TCP协议“三次握手”与“四次挥手”详解(上)
    95题--不同的二叉搜索树II(java、中等难度)
    96题--不同的二叉搜索树(java、中等难度)
    CRC循环冗余校验---模2除法解析
    黑盒测试用例设计方法总结
    软件配置管理和软件维护的区别【详细】
  • 原文地址:https://www.cnblogs.com/sevenyuanluo/p/11837676.html
Copyright © 2020-2023  润新知