zoukankan      html  css  js  c++  java
  • 模板集

     oi各类模板集

    https://www.luogu.org/paste/h3mzcfo1

    https://www.cnblogs.com/phemiku/p/11622062.html

    各种模板题

    1.快速幂与快速乘

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int kase, a, b, q;
    ll c, d, r;
    
    int qpow(int a, int b, int q) {
        ll s = 1;
        while (b) {
            if (b & 1)
                s = s * a % q;
            a = (ll)a * a % q;
            b >>= 1;
        }
        return s;
    }
    
    ll qmul(ll c, ll d, ll r) {
        ll s = 0;
        while (d) {
            if (d & 1)
                s = (s + c) % r;
            c = (c + c) % r;
            d >>= 1;
        }
        return s;
    }
    
    int main() {
        scanf("%d", &kase);
        while (kase--) {
            scanf("%d%d%d%lld%lld%lld", &a, &b, &q, &c, &d, &r);
            printf("%d %lld
    ", qpow(a, b, q), qmul(c, d, r));
        }
    }

    2.归并排序

    //划分问题:把序列分成元素个数尽量相等的两半
    //递归求解:把两半元素分别排序
    //合并问题:把两个有序表合并为一个
    //如果左边最小的数都比右边这个数大,
    //那么左边剩余的所有数都会比右边这个数大
    #include <bits/stdc++.h>
    using namespace std;
    
    #define N 1000005
    int n, a[N], b[N];
    long long cnt;
    
    void merge_sort(int l, int r) {
        if (l < r) {
            int mid = (l + r) / 2;
            int i = l;
            int p = l, q = mid + 1;
            merge_sort(l, mid);
            merge_sort(mid + 1, r);
            while (p <= mid || q <= r)
                if (q > r || (p <= mid && a[p] <= a[q]))
                    b[i++] = a[p++];
                else {
                    b[i++] = a[q++];
                    cnt += mid - p + 1;  //将逆序对的个数累加起来
                }
            for (i = l; i <= r; i++) a[i] = b[i];
        }
    }
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        merge_sort(1, n);
        printf("%lld", cnt);
    }

    3.ST表

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 500009;
    int m, Log[N];
    
    struct ST {
        int st[21][N], n;
        int query(int l, int r) {
            assert(l <= r && r <= n);
            int t = Log[r - l + 1];
            return min(st[t][l], st[t][r - (1 << t) + 1]);
        }
        void push_back(int x) {
            st[0][++n] = x;
            for (int i = 1;; i++) {
                int l = n - (1 << i) + 1;
                if (l >= 1) {
                    st[i][l] = min(st[i - 1][l], st[i - 1][l + (1 << (i - 1))]);
                } else
                    break;
            }
        }
        void pop_back() { n--; }
    } st;
    
    int main() {
        scanf("%d", &m);
        for (int i = 2; i < N; i++) {
            Log[i] = Log[i >> 1] + 1;
        }
    
        while (m--) {
            char opt[9];
            scanf("%s", opt);
            if (opt[0] == 'I') {
                int x;
                scanf("%d", &x);
                st.push_back(x);
            } else if (opt[0] == 'Q') {
                int l, r;
                scanf("%d%d", &l, &r);
                printf("%d
    ", st.query(l, r));
            } else {
                st.pop_back();
            }
        }
        return 0;
    }

    4.左偏树

    // ①:空节点为-1(性质推得)
    // ②:删除操作:将其左右子树合并,接上去即可
    //     插入操作:将插入的点用倍增合成一树,插入即可
    //     替换操作:先删除再插入(注意删除时d[x]=r[x]=v[x]=l[x]=0)
    #include<bits/stdc++.h>
    #define Int register int
    #define N 100005
    using namespace std;
    
    int n,m;
    int fa[N],son[N][2],dead[N],dist[N],val[N];
    
    int read (int &x){
        x = 0;
        char c = getchar();
        int f = 1;
        while(c < '0' || c > '9') {if (c == '-') f = -f;c = getchar();}
        while(c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + c - '0';c = getchar();}
        return x*f; 
    }
    
    void write (int x){
        if(x < 0) {x = -x;putchar ('-');}
        if(x > 9) write (x / 10);
        putchar (x % 10 + '0'); 
    } 
    
    int findSet (int x){
        if (x != fa[x])
            fa[x] = findSet (fa[x]);
        return fa[x];
    }
    
    int Merge (int x,int y){
        if (!x || !y) 
            return x | y;
        //if(x==0)   return y;   //只剩某一子数(点)的情况 
        //if(y==0)   return x;
        //判断到尽头,儿子为空要返回对应的另一结点    
        if (val[x] > val[y] ) 
            swap (x,y);
        //如果值x大于y 或者值相同情况下 x的位置在y右边 交换
        son[x][1] = Merge (son[x][1],y);
        //将y不断地和x的右儿子进行合并
        //将合并后的新的右儿子的父亲边连上
        dist[x] = dist[son[x][1]] + 1;
        //fa[lson[x]]=fa[rson[x]]=fa[x]=x;
        //如果右儿子的dis要大于左儿子 进行交换
        //dis[x]=(rson[x]==0?0:dis[rson[x]]+1);
        //x的dis为其右儿子的dis+1
        //若无右儿子则dis为0
        if (dist[x] > dist[son[x][0]] + 1) 
            swap (son[x][0],son[x][1]);
        fa[son[x][0]] = fa[son[x][1]] = fa[x] = x;
        return x;
    }
    
    int Ask (int x){
        dead[x] = 1;
        int tmp = val[x];
        fa[son[x][0]] = son[x][0];
        fa[son[x][1]] = son[x][1];
        fa[x] = Merge (son[x][0],son[x][1]);
        return tmp;
    }
    
    signed main(){
        read(n),read(m);
        for (Int i = 1;i <= n;++ i) 
            fa[i] = i,read (val[i]);
        for (Int i = 1;i <= m;++ i) {
            int opt;
            read (opt);
            if(opt == 1){
                int x,y;
                read (x),read (y);
                if (dead[x] || dead[y]) continue;
                x = findSet (x),y = findSet (y);
                if (x != y)
                    fa[x] = fa[y] = Merge (x,y);
            } else if(opt == 2){
                int x;
                read (x);
                if(dead[x]) puts ("-1");
                else write (Ask (findSet (x))),putchar ('
    '); 
            }
        }
    }

    5.最短路

    (1)SPFA

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e5 + 9;
    int n, m, mod;
    
    struct Edge {
        int v, w;
        Edge *nxt;
        bool ok;
    } e[N<<1];
    int e_cnt;
    Edge *head[N];
    void addEdge(int u, int v, int w) {
        e[++e_cnt] =(Edge){ v, w, head[u], false };
        head[u] = &e[e_cnt];
    }
    
    int dis[N];
    bool inq[N];
    queue<int> q;
    void SPFA() {
        q.push(1);
        dis[1] = 0;
        inq[1] = true;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (Edge *i = head[u]; i != NULL; i = i->nxt) {
                int v = i->v, w = i->w;
                if (dis[v] > dis[u] + w ) {
                    dis[v] = dis[u] + w;
                    if (!inq[v]) {
                        q.push(v);
                        inq[v] = true;
                    }
                }
            }
            inq[u] = false;
        }
    }
    
    int ind[N], f[N];
    void dp() {
        f[1] = 1;
        q.push(1);
        inq[1] = true;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (Edge *i = head[u]; i != NULL; i = i->nxt) {
                int v = i->v, w = i->w;
                if (dis[v] == dis[u] + w) {
                    i->ok = true;
                    ++ind[v];
                    if (!inq[v]) {
                        q.push(v);
                        inq[v] = true;
                    }
                }
            }
        }
        q.push(1);
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (Edge *i = head[u]; i != NULL; i = i->nxt) {
                if (!(i->ok)) continue;
                int v = i->v, w = i->w;
                f[v] = (f[v] + f[u]) % mod;
                if (--ind[v] == 0)
                    q.push(v);
            }
        }
    }
    
    int main() {
        int kase;
        scanf("%d", &kase);
        while (kase--) {
            scanf("%d%d%d", &n, &m, &mod);
            e_cnt = 0;
            for (int i = 1; i <= n; ++i) {
                head[i] = NULL;
                dis[i] = 1e9;
                f[i] = 0;
                ind[i] = 0;
                inq[i] = false;
            }
            for (int i = 0, x, y, z; i < m; ++i) {
                scanf("%d%d%d", &x, &y, &z);
                addEdge(x, y, z);
            }
            SPFA();
            dp();
            for (int i = 2; i <= n; ++i) 
                printf("%d ", f[i]);
            puts("");
        }
    }

    (2)Dijkstra

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1e7+10;
    int n,m,head[N],tot;
    int dis[N],t,rxa,rxc,rya,ryc,rp;
    
    struct node{
        int to,nxt,w;
    }e[N]; 
    bool inq[N];
    priority_queue<pair<int ,int > >q;
    
    int read(){
        int x=0,f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0'){
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=(x*10+ch-'0');
            ch=getchar();
        }
        return x*f;
    }
    
    void add(int u,int v,int w){
        e[++tot].to=v;
        e[tot].w=w;
        e[tot].nxt=head[u];
        head[u]=tot;
    }
    
    int main(){
        n=read(),m=read(),t=read();
        rxa=read(),rxc=read(),rya=read(),ryc=read();
        rp=read();
        int x=rxc%rp,y=ryc%rp;
        int a = min(x%n+1,y%n+1) , b=y%n+1;
        add(a,b,1e8-100*a);
        for(int i=1;i<=m-t;i++){
            int xx,yy,zz;
            xx=read(),yy=read(),zz=read();
            add(xx,yy,zz);
        } 
        
        memset(dis,0x3f,sizeof dis);
        dis[1]=0;
        q.push(make_pair(0,1));
        inq[1]=0;
        while(!q.empty()){
            int x=q.top().second;
            q.pop();
            if(inq[x]) continue;
            inq[x]=1;
            for(int i=head[x];i;i=e[i].nxt){
                int to=e[i].to,w=e[i].w;
                if(dis[to]>dis[x]+w){
                    dis[to]=dis[x]+w;
                    q.push(make_pair(-dis[to],to));
                }
            }
        }
        printf("%d",dis[n]);
    }

    (3) BFS 

    最短路计数(求1到其他顶点的最短路条数)

    ( 边权为1时 )

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1e6+5,M=4e6+5;
    int mod=1e5+3;
    int n,m,x,y,tot;
    int head[N],to[N],nxt[M],d[N],ans[N];
    bool p[N];
    queue<int>q;
    
    void add(int x,int y){
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    } 
    
    int main(){
        scanf("%d%d",&n,&m);
        while(m){
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
            m--;
        }
        for(int i=1;i<=n;i++){
            d[i]=1e9;
            p[i]=0; 
        }
        d[1]=0;
        p[1]=1;
        ans[1]=1;
        q.push(1);
        while(q.size()){
            x=q.front();
            q.pop();
            p[x]=0;
            for(int i=head[x];i;i=nxt[i]){
                y=to[i];
                if(d[y]>d[x]+1){
                    d[y]=d[x]+1;
                    ans[y]=ans[x];
                    if(!p[y]){
                        q.push(y);
                        p[y]=1;
                    }
                }
                else if(d[y]==d[x]+1){
                    ans[y]+=ans[x];
                    ans[y]%=mod;
                }
            }
        }
        for(int i=1;i<=n;i++)
            printf("%d
    ",ans[i]);
    }

    6.MST(最小生成树)

    (1)洛谷模板题

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 400015;
    
    struct edge {
        int u,v,w;
    } edges[N];
    int n, m, cnt, tot,fa[N];
    long long ans;
    
    bool cmp(edge x, edge y) { return x.w < y.w; }
    
    int find(int x) {
        if(x == fa[x]) return x;
        else return fa[x] = find(fa[x]);
    }
    
    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return 0;
        fa[x] = y;
        return 1;//??
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++) {
            int x, y, p;
            scanf("%d%d%d", &x, &y, &p);
            edges[++tot] = (edge){ x, y, p };
        }
        sort(edges + 1, edges + 1 + tot, cmp);
        for (int i = 1; i <= n; i++) fa[i] = i;
        for (int i = 1; i <= tot; i++) {
            int u = edges[i].u;
            int v = edges[i].v;
            if (merge(u, v)) {
                ans += edges[i].w;
                cnt++;
            }
            if (cnt == n - 1) break;
        }
        if (cnt != n - 1) printf("orz"); //什么鬼输出
        else printf("%lld", ans);
    }

    (2)

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 200010;
    
    struct Edge {
        int to, w;
    };
    vector<Edge> G[N];
    
    int n, m, done[N];
    
    struct Node {
        int d, v;
        bool operator<(const Node &rhs) const { return d > rhs.d; }
    };
    priority_queue<Node> q;
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < m; i++) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            G[u].push_back((Edge){ v, w });
            G[v].push_back((Edge){ u, w });
        }
    
        q.push((Node){ 0, 1 });
        long long ans = 0;
        for (int i = 1; i <= n; i++) {
            Node u;
            do {
                if (!q.size()) {
                    puts("-1");
                    return 0;
                }
                u = q.top();
                q.pop();
            } while (done[u.v]);
            ans += u.d;
            done[u.v] = 1;
            for (unsigned i = 0; i < G[u.v].size(); i++) {
                Edge &e = G[u.v][i];
                q.push((Node){ e.w, e.to });
            }
        }
        cout << ans << endl;
    }

    7.线段树

    //线段树 
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    const int N=2e5+9; 
    int n,m;
    ll sum[N<<2]/*4倍空间*/,tag[N<<2];
    
    void pushup(int u){
        sum[u]=sum[u<<1]+sum[u<<1|1];
    }
    
    void buildtree(int u,int ul,int ur){
        if(ul==ur){//如果是叶节点 
            scanf("%ll",sum+u);
            return;
        }
        int mid=ul+ur>>1;
        buildtree(u<<1,ul,mid);
        buildtree(u<<1|1,mid+1,ur);
        pushup(u);
    }
    
    void update(int u,int ul,int ur,int mx){
        tag[u]+=mx;
        sum[u]+=(ll)mx*(ur-ul+1);
    }
    
    void pushdown(int u,int ul,int ur){
        if(tag[u]){
            int mid=ul+ur>>1;
            update(u<<1,ul,mid,tag[u]);
            update(u<<1|1,mid+1,ur,tag[u]);
            tag[u]=0;
        }
    }
    
    void modify(int u,int ul,int ur,int ml,int mr,int mx){
        if(ml<=ul&&ur<=mr){
            update(u,ul,ur,mx);
            return;
        }
        pushdown(u,ul,ur);
        int mid=ul+ur>>1;
        if(ml<=mid)
            modify(u<<1,ul,mid,ml,mr,mx);
        if(mr>=mid+1)
            modify(u<<1|1,mid+1,ur,ml,mr,mx);
        pushup(u);
    }
    
    ll query(int u,int ul,int ur,int ml,int mr){
        if(ml<=ul&&ur<=mr)
            return sum[u];
        pushdown(u,ul,ur);
        int mid=ul+ur>>1;
        ll s=0;
        if(ml<=mid)
            s+=query(u<<1,ul,mid,ml,mr);
        if(mr>=mid+1)
            s+=query(u<<1|1,mid+1,ur,ml,mr);
        return s;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        buildtree(1,1,n);
        while(m--){
            int opt,x,y,z;
            scanf("%d%d%d",&opt,&x,&y);
            if(opt==0){
                scanf("%d",&z);
                modify(1,1,n,x,y,z);//修改函数 
            } else{
                printf("%ll
    ",query(1,1,n,x,y));
            } 
        }
    }

    8.树状数组

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N = 200005;
    int n, m;
    ll a[N], d[N], id[N];
    
    int lowbit(int x){ return x&(-x); }
    //算出x二进制的从右往左出现第一个1以及这个1之后的那些0组成数的二进制对应的十进制的数
    //就是看区间和包括的数的个数 
    //-x代表x的负数,用对应的正数的补码来表示。
    
    void modify(ll *t, int i, ll x) {
        while (i <= n) { //不能越界 
            t[i] += x;
            i += lowbit(i);
        }
    }
    
    ll query(ll *t, int i) { //a[1]……a[x]的和 
        ll sum = 0;
        while (i) {
            sum += t[i];
            i -= lowbit(i);
        }
        return sum;
    }
    
    ll q(int r) { return query(d, r) * (r + 1) - query(id, r); }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &a[i]);
            modify(d, i, a[i] - a[i - 1]);
            modify(id, i, i * (a[i] - a[i - 1]));
        }
        while (m--) {
            ll opt, x, y, z;
            scanf("%lld%lld%lld", &opt, &x, &y);
            if (opt == 0) {
                scanf("%lld", &z);
                modify(d, x, z);
                modify(id, x, x * z);
                modify(d, y + 1, -z);
                modify(id, y + 1, (y + 1) * (-z));
            } else
                printf("%lld
    ", (q(y) - q(x - 1)));
        }
        return 0;
    }

    9.拓扑序

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+5;
    
    int n,m,du[N],f[N],cnt;
    stack<int>s;
    
    struct Edge{
        int next,to;
    }edge[N<<1];
    int tot,head[N];
    void add(int from,int to){
        edge[++tot].next=head[from];
        edge[tot].to=to;
        head[from]=tot;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            add(v,u);
            du[u]++;
        }
        for(int i=1;i<=n;i++){
            f[i]=1;
            if(du[i]==0) s.push(i);
        }
        while(!s.empty()){
            int u=s.top();
            s.pop();
            ++cnt;
            for(int i=head[u];i;i=edge[i].next ){
                int v=edge[i].to;
                f[v]=max(f[v],f[u]+1);
                du[v]--;
                if(du[v]==0) s.push(v);
            }
        }
        if(cnt<n){
            printf("-1
    ");
            return 0;
        }
        long long ans=0;
        for(int i=1;i<=n;i++) 
            ans+=f[i];
        printf("%lld",ans);
    }

    10.并查集

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 50000 + 10;
    int fa[N], val[N];
    
    int find(int x) {
        if (fa[x] == x)
            return x;
        int tmp = find(fa[x]);
        (val[x] += val[fa[x]]) %= 3;
        return fa[x] = tmp;
    }
    
    bool merge(int x, int y, int d) {
        int fx = find(x), fy = find(y);
        if (fx == fy)
            return (val[x] - val[y] - d) % 3 == 0 ? 1 : 0;
        fa[fy] = fx;
        val[fy] = (val[x] - val[y] - d + 6) % 3;
        return 1;
    }
    
    int main() {
        int n, k, ans = 0;
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++) fa[i] = i, val[i] = 0;
        while (k--) {
            int d, a, b;
            scanf("%d%d%d", &d, &a, &b);
            if (a > n || b > n || !merge(a, b, d - 1))
                ans++;
        }
        printf("%d
    ", ans);
    
        return 0;
    }

    11.高精加减乘

    #include <bits/stdc++.h>
    using namespace std;
    //compare比较函数:相等返回0,大于返回1,小于返回-1
    int compare(string str1,string str2) {
        if(str1.length()>str2.length()) return 1;
        else if(str1.length()<str2.length()) return -1;
        else return str1.compare(str2);
    }
    //高精度加法
    //只能是两个正数相加
    string add(string str1,string str2) {
        string str;
        int len1=str1.length();
        int len2=str2.length();
        //前面补0,弄成长度相同
        if(len1<len2) {
            for(int i=1;i<=len2-len1;i++)
               str1="0"+str1;
        } else {
            for(int i=1;i<=len1-len2;i++)
               str2="0"+str2;
        }
        len1=str1.length();
        int cf=0, temp;
        for(int i=len1-1;i>=0;i--) {
            temp=str1[i]-'0'+str2[i]-'0'+cf;
            cf=temp/10;
            temp%=10;
            str=char(temp+'0')+str;
        }
        if(cf!=0)  
            str=char(cf+'0')+str;
        return str;
    }
    //高精度减法
    //只能是两个正数相减,而且要大减小
    string sub(string str1,string str2) {
        string str;
        int tmp=str1.length()-str2.length();
        int cf=0;
        for(int i=str2.length()-1;i>=0;i--) {
            if(str1[tmp+i]<str2[i]+cf) {
                str=char(str1[tmp+i]-str2[i]-cf+'0'+10)+str;
                cf=1;
            } else {
                str=char(str1[tmp+i]-str2[i]-cf+'0')+str;
                cf=0;
            }
        }
        for(int i=tmp-1;i>=0;i--) {
            if(str1[i]-cf>='0') {
                str=char(str1[i]-cf)+str;
                cf=0;
            } else {
                str=char(str1[i]-cf+10)+str;
                cf=1;
            }
        }
        str.erase(0,str.find_first_not_of('0'));//去除结果中多余的前导0
        return str;
    }
    //高精度乘法
    //只能是两个正数相乘
    string mul(string str1,string str2) {
        string str;
        int len1=str1.length();
        int len2=str2.length();
        string tem;
        for(int i=len2-1;i>=0;i--) {
            tem ="";
            int temp=str2[i]-'0';
            int t=0, cf=0;
            if(temp!=0)  {
                for(int j=1;j<=len2-1-i;j++)
                  tem +="0";
                for(int j=len1-1;j>=0;j--) {
                    t=(temp*(str1[j]-'0')+cf)%10;
                    cf=(temp*(str1[j]-'0')+cf)/10;
                    tem =char(t+'0')+tem;
                }
                if(cf!=0) tem =char(cf+'0')+tem;
            }
            str=add(str,tem);
        }
        str.erase(0,str.find_first_not_of('0'));
        return str;
    }
    //高精度除法
    //两个正数相除,商为quotient,余数为residue
    //需要高精度减法和乘法
    void div(string str1,string str2,string &quo,string &resi) {
        quo =resi ="";//清空
        if(str2=="0") {//判断除数是否为0
            quo =resi ="ERROR";
            return;
        }
        if(str1=="0") {//判断被除数是否为0
            quo =resi ="0";
            return;
        }
        int res=compare(str1,str2);
        if(res<0) {
            quo ="0";
            resi =str1;
            return;
        } else if(res==0) {
            quo ="1";
            resi ="0";
            return;
        } else {
            int len1=str1.length();
            int len2=str2.length();
            string tem ;
            tem .append(str1,0,len2-1);
            for(int i=len2-1;i<len1;i++) {
                tem =tem +str1[i];
                tem .erase(0,tem .find_first_not_of('0'));
                if(tem .empty())
                      tem ="0";
                for(char ch='9';ch>='0';ch--) {//试商
                    string str,tmp;
                    str=str+ch;
                    tmp=mul(str2,str);
                    if(compare(tmp,tem )<=0) {//试商成功
                        quo =quo +ch;
                        tem =sub(tem ,tmp);
                        break;
                    }
                }
            }
            resi =tem ;
        }
        quo .erase(0,quo .find_first_not_of('0'));
        if(quo .empty()) 
            quo ="0";
    }
    
    int main() {
        string a, b, c, d;
        cin >> a >> b;
        div(a, b, c, d);
        cout << c;
    } 

    12.压位+floyd

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 2005;
    int f[N][N], n;
    
    int main() {
        scanf("%d", &n);
        for (int i = 0; i < n; i++) {
            char a[N];
            scanf("%s", &a);
            a[i] = '1';  //对角线上的
            for (int j = 0; j < n; j++)
                if (a[j] - '0' == 1) {
                    int k = j % 32;
                    f[i][j / 32] |= 1 << k;  // 1左移k位,加入集合
                }
        }
        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) {
                if (i == k)
                    continue;
                if (!(f[i][k / 32] & 1 << (k % 32)))  // i能到达k
                    continue;
                for (int j = 0; j <= n / 32; j++) f[i][j] = f[k][j] | f[i][j];  //从k能到j的并上从i到j的
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= n / 32; j++)
                for (int k = 0; k <= 31 && j * 32 + k < n; k++)  //遍历k位
                    putchar(((f[i][j] >> k) & 1) + '0');         //看每一位能否到达
            printf("
    ");                                        // puts("");换行
        }
    }

    13.Lucas

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int N = 200005;
    ll a[N];
    int p;
    
    int read() {
        int x = 0, f = 1;
        char ch = getchar();
        while (ch > '9' || ch < '0') {
            if (ch == '-') f= -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = (x << 3) + (x << 1) + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    ll pow(ll a, ll b, ll mod) {
        ll ans = 1;
        while (b) {
            if (b & 1)
                ans = ans * a % mod;
            b >>= 1;
            a = a * a % mod; 
        }
        return ans;
    }
    
    ll C(ll n, ll m) {//求阶乘
        ll ans = 1;
        for (int i = n - m + 1; i <= n; i++)
            ans = ans * i % p;
        return ans;
    }
    
    ll Lucas(ll n, ll m) { //卢卡斯定理
        if (!m) return 1;
        if (n < p && m < p)
            return C(n, m) * pow(a[m], p - 2, p) % p;
        return Lucas(n % p, m% p) * Lucas(n / p, m / p) % p;
    }
    
    int main() {
        int T = read();
        while (T--) {
            int n = read(), m = read();
            p = read();
            a[0] = 1;
            for (int i = 1; i <= m; i++)
                a[i] = (a[i - 1] * i) % p; //预处理阶乘到m
            cout << Lucas(n, m) << endl;
        }
    }

    14.LCA

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 20050;
    vector<int> to[N];
    int n,m,f[N][20], d[N], bu[N][N], cnt[N], ans[N], fa[N];
    
    void insert(int u, int v) { 
        to[u].push_back(v); 
    }
    
    void dfs(int u, int h) {
        for (unsigned int i = 0; i < to[u].size(); i++) {
            int v = to[u][i];
            if (v != fa[u]) {
                d[v] = h;
                cnt[v] = cnt[u] + bu[v][u];
                fa[v] = u;
                dfs(v, h + 1);
            }
        }
    }
    
    void init() {
        for (int i = 1; i <= n; i++)
            f[i][0] = fa[i];
        for (int j = 1; j <= 19; j++)
            for (int i = 1; i <= n; i++)
                f[i][j] = f[f[i][j - 1]][j - 1];
    }
    
    int lca(int u, int v) {
        if (d[u] != d[v]) {
            if (d[u] > d[v])
                swap(u, v);
            int x = d[v] - d[u], j = 0;
            while (x) {
                if (x & 1)
                    v = f[v][j];
                x >>= 1;
                j++;
            }
        }
        if (u == v)
            return u;
        for (int i = 19; i >= 0; i--) {
            if (f[u][i] != f[v][i]) {
                u = f[u][i];
                v = f[v][i];
            }
        }
        return fa[u];
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i = 1; i < n; i++) {
            int b, c, t;
            scanf("%d%d%d",&b,&c,&t);
            insert(c, b);
            insert(b, c);
            bu[b][c] = t;
            bu[c][b] = t;
        }
    
        d[1] = 1;
        dfs(1, 2);
    
        init();
        for (int i = 1; i <= m; i++) {
            int x, y;
            scanf("%d%d",&x,&y);
            ans[i] = cnt[x] + cnt[y] - 2 * cnt[lca(x, y)];
        }
    
        for (int i = 1; i <= m; i++)
            cout << ans[i] << endl;
    }

    15.二分

    #include<bits/stdc++.h>
    #define N 2000005
    using namespace std;
    
    int n,m,l,ans,a[N];
    
    int judge(int x){
        int s=0,num=0;
        for(int i=1;i<=n;i++){
            if(a[i]-s<x) num++;
            else s=a[i];
        }
        if(num>m) return 0;
        return 1;
    }
    
    int main(){
        scanf("%d%d%d",&l,&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        a[n+1]=l;
        int le=0,ri=l;
        while(le<=ri){
            int mid=le+ri>>1;
            if(judge(mid)){
                le=mid+1;
                ans=mid;
            }
            else ri=mid-1;
        }
        printf("%d",ans);
    }

    16.堆

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 100010;
    int n, m,a[N];  // n表示堆里还有多少个节点,n是变的,所以弄个不变的m
    
    void update(int x) {  //左移代表乘以二,就代表左儿子 //x<<1|1表示乘以二加一
        if ((x << 1) > n)
            return;
        int y = x << 1;  //如果只有一个儿子,y就是唯一的儿子,如果有两个,y就是更大的那个儿子
        if ((y | 1) <= n && a[y | 1] < a[y])
            y = y | 1;
        if (a[y] >= a[x])
            return;
        swap(a[x], a[y]);
        update(y);
    }
    
    int main() {
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        for (int i = n >> 1; i >= 1; i--) update(i);
        for (int i = 1; i <= m; i++) {
            int temp;
            scanf("%d", &temp);
            if (temp == 1) {
                scanf("%d", &a[++n]);
                for (int i = n >> 1; i >= 1; i = i >> 1) update(i);
            } else if (temp == 2) {
                printf("%d", a[1]);
                puts("");
                swap(a[1], a[n]);
                n--;
                update(1);
            }
        }
    }

    17.单调队列

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1000005;
    int ai[N], maxq[N], minq[N];
    int n, m, c, ahead, ihead, ansn, atail = 1, itail = 1;
    
    int main() {
        scanf("%d%d%d",&n, &m, &c);
        for (int i = 1; i <= n; i++) scanf("%d", ai + i);
        
        for (int i = 1; i <= n; i++) {
            while (ahead >= atail && ai[maxq[ahead]] <= ai[i]) --ahead;
             
            ++ahead;
            maxq[ahead] = i;
             
            while (ihead >= itail && ai[minq[ihead]] >= ai[i]) --ihead;
             
            ++ihead;
            minq[ihead] = i;
             
            if (maxq[atail] <= i - m) ++atail;
            if (minq[itail] <= i - m) ++itail;
            
            if (i >= m)
                if (ai[maxq[atail]] - ai[minq[itail]] <= c) {
                    printf("%d
    ", i - m + 1);
                    ++ansn;
                }
        }
        if(!ansn)
            printf("NONE");
    }

    18.欧几里得(辗转相除)

    ll gcd(ll a, ll b) { return !b ? a : gcd(b, a%b); }

    19.扩展欧几里得

     青蛙的约会:https://www.luogu.org/problem/P1516

    int exgcd(int a,int b,int &x,int &y){
        if(b == 0){
            x = 1, y = 0;
            return a; 
        } 
        int ret = exgcd(b, a%b, x, y);
        int tmp = x;
        x = y;
        y = tmp - a/b*y;
        return ret;
    }

    20.差分、前缀和

    ·区间修改后询问 http://oj.ipoweru.cn/problem/24200

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long lld;
    
    const int N = 1e6 + 9;
    int n, m, q;
    lld a[N], d[N], s[N];
    
    int main() {
        scanf("%d%d%d", &n, &m, &q);
        for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
        for (int i = 1; i <= n; ++i) d[i] = a[i] - a[i - 1];
        for (int i = 1, x, y, z; i <= m; ++i) {
            scanf("%d%d%d", &x, &y, &z);
            d[y + 1] -= z;
            d[x] += z;
        }
        for (int i = 1; i <= n; ++i) a[i] = a[i - 1] + d[i];
        for (int i = 1; i <= n; ++i) s[i] = s[i - 1] + a[i];
        for (int i = 1, x, y; i <= q; ++i) {
            scanf("%d%d", &x, &y);
            printf("%lld
    ", s[y] - s[x - 1]);
        }
    }

    21.分解质因数

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    
    int T, n, t, sta[1000000], tot;
    
    int mul(int a, int b, int mod) {
        int ans = 0;
        while (b) {
            if (b & 1)
                ans = (ans + a) % mod;
            a = (a + a) % mod;
            b >>= 1;
        }
        return ans;
    }
    
    int g(int x, int mod, int c) { return (mul(x, x, mod) + c) % n; }
    
    int qpow(int a, int b, int mod) {
        int ans = 1;
        while (b) {
            if (b & 1)
                ans = mul(ans, a, mod);
            b >>= 1;
            a = mul(a, a, mod);
        }
        return ans;
    }
    
    bool MillerRabin(int n) {
        if (n == 2)
            return 1;
        if (n < 2 || !(n & 1))
            return 0;
        int m = n - 1, k = 0;
        while (!(m & 1)) {
            k++;
            m >>= 1;
        }
        for (int i = 1; i <= 3; i++) {
            int a = rand() % (n - 1) + 1;
            int x = qpow(a, m, n);
            int y;
            for (int j = 1; j <= k; j++) {
                y = mul(x, x, n);
                if (y == 1 && x != 1 && x != n - 1)
                    return 0;
                x = y;
            }
            if (y != 1)
                return 0;
        }
        return 1;
    }
    
    int check(int n, int c) {
        int a = 2, b = a,p = 1;
        do {
            a = g(a, n, c);
            b = g(g(b, n, c), n, c);
            p = __gcd(abs(a - b), n);
            if (p != 1) break;
        } while (a != b);
        if (a == b) return 0;
        else return p;
    }
    
    void solve(int n) {
        while (n % 2 == 0) {  // n为偶数
            n /= 2;
            sta[++tot] = 2;
        } 
        if (n == 1)
            return;
        if (MillerRabin(n))
            sta[++tot] = n;
        else {
            int d = n;
            int i = 1;
            while (i++) {
                d = check(n, i);
                if (d != n)
                    break;
            }
            solve(d);
            solve(n / d);
        }
    }
    
    signed main() {
        srand(time(0));
        cin >> T;
        while (T--) {
            tot = 0;
            cin >> n;
            solve(n);
            sort(sta + 1, sta + tot + 1);
            for (int i = 1; i <= tot; i++) {
                cout << sta[i] << " ";
            }
            cout << endl;
        }
    }

    22.卷积式

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int N = 3505;
    int T, n, m, q;
    ll f[N], g[N];
    
    void work(int n) {
        if (n == 1) return;
        
        if (!(n & 1)) {//n&1判断奇偶.当n为奇数时,返回1;当n为偶数时,返回0
            //为偶数 
            work(n / 2);
            
            for (int i = 0; i <= m; i++) {
                g[i] = 0;
                for (int j = 0; j <= i; j++) 
                    g[i] += f[j] % q * f[i - j] % q;
                g[i] %= q;
            }
            
            for (int i = 0; i <= m; i++) 
                f[i] = g[i];
                
        } else { //奇数 
            work(n - 1);
            
            for (int i = 1; i <= m; i++) {
                g[i] = f[i - 1] % q + f[i] % q;
                g[i] %= q;
            }
            
            for (int i = 1; i <= m; i++) 
                f[i] = g[i];
                
        }
    }
    
    signed main() {
        scanf("%d",&T);
        while (T--) {
            scanf("%d%d%d",&n,&m,&q);
            memset(f, 0, sizeof f);
            f[0] = f[1] = 1;
            work(n);
            for (int i = 0; i <= m; i++)
                printf("%lld ",f[i] % q);
            puts("");
        }
    }

    23.容斥原理

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int N=2003;
    int n, m, f[N][N], a[N], c[N];
    ll p, ans;
    
    void getpre() {
        for (int i = 0; i <= n + 1; i++) {
            f[i][0] = 1;
            f[i][i] = 1;
        }
        for (int i = 1; i <= n + 1; i++)
            for (int j = 1; j <= i; j++)
                f[i][j] = (f[i - 1][j] + f[i - 1][j - 1]) % p;
    }
    
    void dfs(int k, int s, int sum) {
        if (sum <= 0) return;
        if (k == m + 1) {
            ans = (ans + s * f[sum - 1][m - 1] % p + p) % p;
            return;
        }
        dfs(k + 1, s, sum);
        dfs(k + 1, -s, sum - c[k] - 1);
    }
    
    int main() {
        scanf("%d%d%lld", &m, &n, &p);
        int num = 0;
        getpre();
    
        for (int i = 1; i <= m; i++) {
            scanf("%d%d",&a[i],&c[i]);
            c[i] -= a[i];
            num += a[i];
        }
    
        dfs(1, 1, n + m - num);
        printf("%lld", ans);
    }

     24.重载

    //重载运算符比较大小
    struct node {  int len;   
       bool operator <(const node &a)const {//重载<操作符。可以对两个node使用<操作符进行比较
           return len<a.len;
       }
    };
  • 相关阅读:
    Spring整合CXF之添加拦截器
    Spring整合CXF之发布WebService服务
    CXF添加自定义拦截器
    cxf处理一些Map等复杂类型
    webservice执行过程深入理解
    谈谈房车
    关于贷款消费
    记一次玩比特币的经历
    那年K城暑期工
    SpringBoot整合Xxl-Job
  • 原文地址:https://www.cnblogs.com/aprincess/p/11826140.html
Copyright © 2011-2022 走看看