zoukankan      html  css  js  c++  java
  • 模板

    图论:

    最小生成树

    kruskal

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=5000+50;
    const int maxm=200000+50;
    
    int n,m,fat[maxn];
    
    struct node{int x,y,z;}a[maxm];
    int cmp(const node &a,const node &b){return a.z<b.z;}
    
    int father(int x){
        if(x!=fat[x]) fat[x]=father(fat[x]);
        return fat[x];
    }
    
    void kruskal(){
        int k=0,ans=0;
        for(int i=1;i<=m;i++){
            int fa=father(a[i].x);
            int fb=father(a[i].y);
            if(fa!=fb){
                fat[fa]=fb;
                k++;
                ans+=a[i].z;
            }
            if(k==n-1) break;
        }
        if(k==n-1) printf("%d",ans);
        else printf("orz");
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n),read(m);
        for(int i=1;i<=n;i++) fat[i]=i;
        for(int i=1;i<=m;i++) read(a[i].x),read(a[i].y),read(a[i].z);
        sort(a+1,a+1+m,cmp);
        kruskal();
        return 0;
    }
    View Code

    kruskal重构树

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=200000+50;
    
    int n,m,k,aa,bb,fat[maxn],cnt;
    int fir[maxn],to[maxn],nex[maxn],ecnt;
    int son[maxn],dep[maxn],sz[maxn],fa[maxn],top[maxn],val[maxn];
    
    struct node{int x,y,z;}a[maxn];
    
    void add_edge(int u,int v){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;
    }
    
    int cmp(const node &a,const node &b){
        return a.z<b.z;
    }
    
    int father(int x){
        if(x!=fat[x]) fat[x]=father(fat[x]);
        return fat[x];
    }
    
    void dfs1(int x,int f,int deep){
        dep[x]=deep;
        fa[x]=f;
        sz[x]=1;
        int maxson=-1;
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==f) continue;
            dfs1(v,x,deep+1);
            sz[x]+=sz[v];
            if(sz[v]>maxson) maxson=sz[v],son[x]=v;
        }
    }
    
    void dfs2(int x,int topf){
        top[x]=topf;
        if(!son[x]) return ;
        dfs2(son[x],topf);
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==fa[x]||v==son[x]) continue;
            dfs2(v,v);
        }
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    void kruskal(){
        sort(a+1,a+1+m,cmp);
        for(int i=1;i<=m;i++){
            if(father(a[i].x)!=father(a[i].y)){
                int fa=father(a[i].x),fb=father(a[i].y);
                val[++cnt]=a[i].z;
                fat[cnt]=fat[fa]=fat[fb]=cnt;
                add_edge(fa,cnt);
                add_edge(cnt,fa);
                add_edge(fb,cnt);
                add_edge(cnt,fb);
            }
        }
    }
    
    int lca(int x,int y){
        int f1=top[x],f2=top[y];
        while(f1!=f2){
            if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
            x=fa[f1];f1=top[x];
        }
        return dep[x]<dep[y]?x:y;
    }
    
    int main(){
        read(n),read(m),read(k);cnt=n;
        for(int i=1;i<=m;i++)
        read(a[i].x),read(a[i].y),read(a[i].z);
        for(int i=1;i<=n;i++) fat[i]=i;
        kruskal();
        dfs1(cnt,0,1);dfs2(cnt,cnt);
        while(k--){
            read(aa),read(bb);
            cout<<val[lca(aa,bb)]<<endl;
        }
        return 0;
    }
    View Code

    最短路

    floyed

    void floyd(){
        memset(dis,63,sizeof(dis));
        for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    }
    View Code

    spfa

    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=10000+50;
    const int maxm=500000+50;
    const int inf=2147483647;
    
    int n,m,s,d[maxn];
    int fir[maxn],nex[maxm],to[maxm],wi[maxm],ecnt;
    bool vis[maxn];
    
    queue<int> q;
    
    void add(int u,int v,int w){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;wi[ecnt]=w;
    }
    
    void spfa(int x){
        memset(vis,false,sizeof(vis));vis[x]=true;
        for(int i=1;i<=n;i++) d[i]=inf;d[x]=0;
        q.push(x);
        while(!q.empty()){
            int u=q.front();q.pop();
            vis[u]=false;
            for(int e=fir[u];e;e=nex[e]){
                int v=to[e];
                if(d[v]>d[u]+wi[e]){
                    d[v]=d[u]+wi[e];
                    if(!vis[v]){
                        q.push(v);
                        vis[v]=true;
                    }
                }
            }
        }
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n),read(m),read(s);
        for(int i=1;i<=m;i++){
            int x,y,z;
            read(x),read(y),read(z);
            add(x,y,z);
        }
        spfa(s);
        for(int i=1;i<=n;i++) printf("%d ",d[i]);
        return 0;
    }
    View Code

    dijsktra

    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=100000+50;
    const int maxm=200000+50;
    
    int n,m,s,d[maxn];
    int fir[maxn],nex[maxm],to[maxm],wi[maxm],ecnt;
    bool vis[maxn];
    
    priority_queue<pair<ll,int> > q;
    
    void add(int u,int v,int w){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;wi[ecnt]=w;
    }
    
    void dijsktra(int x){
        memset(vis,false,sizeof(vis));
        memset(d,127,sizeof(d));d[x]=0;
        q.push(make_pair(0,x));
        while(!q.empty()){
            int u=q.top().second;q.pop();
            if(vis[u]) continue;
            vis[u]=true;
            for(int e=fir[u];e;e=nex[e]){
                int v=to[e];
                if(d[v]>d[u]+wi[e]){
                    d[v]=d[u]+wi[e];
                    q.push(make_pair(-d[v],v));
                }
            }
        }
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n),read(m),read(s);
        for(int i=1;i<=m;i++){
            int x,y,z;
            read(x),read(y),read(z);
            add(x,y,z);
        }
        dijsktra(s);
        for(int i=1;i<=n;i++) printf("%d ",d[i]);
        return 0;
    }
    View Code

    tarjan

    强连通分量

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=10000+50;
    const int maxm=50000+50;
    
    int fir[maxn],nex[maxm],to[maxm],ecnt;
    int col[maxn],dfn[maxm],low[maxm],stack[maxm],vis[maxn],cnt[maxn];
    int n,m,t,deep,sum,ans,x,y;
    
    void add_edge(int u,int v){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int tarjan(int u){
        dfn[u]=++deep;
        low[u]=deep;
        vis[u]=1;
        stack[++t]=u;
        for(int e=fir[u];e;e=nex[e]){
            int v=to[e];
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else{
                if(vis[v]) low[u]=min(low[u],dfn[v]);
            }
        }
        if(dfn[u]==low[u]){
            col[u]=++sum;
            vis[u]=0;
            while(stack[t]!=u){
                col[stack[t]]=sum;
                vis[stack[t--]]=0;
            }
            t--;
        }
    }
    
    int main(){
        read(n),read(m);
        for(int i=1;i<=m;i++){
            read(x),read(y);
            add_edge(x,y);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i]) tarjan(i);
        }
        for(int i=1;i<=n;i++) cnt[col[i]]++;
        for(int i=1;i<=sum;i++){
            if(cnt[i]>1) ans++;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    最近公共祖先

    倍增

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=500000+5;
    const int maxm=500000*2+5;
    
    int n,m,s,x,y,a,b;
    int fir[maxn],to[maxm],nex[maxm],ecnt;
    int anc[maxn][22],lg[maxn],dep[maxn];
    
    void add_edge(int u,int v){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    void dfs(int u,int fa){
        dep[u]=dep[fa]+1;anc[u][0]=fa;
        for(int i=1;(1<<i)<=dep[u];i++)
        anc[u][i]=anc[anc[u][i-1]][i-1];
        for(int e=fir[u];e;e=nex[e])
        if(to[e]!=fa) dfs(to[e],u);
    }
    
    int lca(int x,int y){
        if(dep[x]<dep[y]) swap(x,y);
        while(dep[x]>dep[y]) x=anc[x][lg[dep[x]-dep[y]]-1];
        if(x==y) return x;
        for(int k=lg[dep[x]];k>=0;k--)
        if(anc[x][k]!=anc[y][k]) x=anc[x][k],y=anc[y][k];
        return anc[x][0];
    }
    
    int main(){
        read(n),read(m),read(s);
        for(int i=1;i<n;i++){
            read(x),read(y);
            add_edge(x,y);add_edge(y,x);
        }
        dfs(s,0);
        for(int i=1;i<=n;i++)
        lg[i]=lg[i-1]+(1<<lg[i-1]==i);
        for(int i=1;i<=m;i++){
            read(a),read(b);
            printf("%d
    ",lca(a,b));
        }
        return 0;
    }
    View Code

    树剖

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=500000+50;
    const int maxm=500000*2+50;
    
    int n,m,s;
    int fir[maxn],nex[maxm],to[maxm],ecnt;
    int fa[maxn],top[maxm],sz[maxn],son[maxn],dep[maxn];
    
    void add(int u,int v){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;
    }
    
    void dfs1(int x,int f,int deep){
        fa[x]=f;
        dep[x]=deep;
        sz[x]=1;
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==f) continue;
            dfs1(v,x,deep+1);
            sz[x]+=sz[v];
            if(sz[v]>sz[son[x]]) son[x]=v;
        }
    }
    
    void dfs2(int x,int topf){
        top[x]=topf;
        if(!son[x]) return ;
        dfs2(son[x],topf);
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==fa[x]||v==son[x]) continue;
            dfs2(v,v);
        }
    }
    
    int lca(int x,int y){
        int f1=top[x],f2=top[y];
        while(f1!=f2){
            if(dep[f1]<dep[f2]) swap(x,y),swap(f1,f2);
            x=fa[f1];f1=top[x];
        }
        return dep[x]<dep[y]?x:y;
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n),read(m),read(s);
        for(int i=1;i<n;i++){
            int x,y;
            read(x),read(y);
            add(x,y);add(y,x);
        }
        dfs1(s,0,1);
        dfs2(s,s);
        while(m--){
            int x,y;
            read(x),read(y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
    View Code

    树链剖分

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=1e5+50;
    const int maxm=2e5+50;
    
    int n,m,r,p,val[maxn],cnt;
    int fir[maxn],nex[maxm],to[maxm],ecnt;
    int son[maxn],dep[maxn],sz[maxn],top[maxn],fa[maxn],id[maxn],wt[maxn];
    
    struct SegmentTree{int l,r;ll v,add;}st[maxn<<2];
    
    void add(int u,int v){
        nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v;
    }
    
    void dfs1(int x,int f,int deep){
        fa[x]=f;dep[x]=deep;
        sz[x]=1;
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==f) continue;
            dfs1(v,x,deep+1);
            sz[x]+=sz[v];
            if(sz[v]>sz[son[x]]) son[x]=v;
        }
    }
    
    void dfs2(int x,int topf){
        top[x]=topf;
        id[x]=++cnt;
        wt[cnt]=val[x];
        if(!son[x]) return ;
        dfs2(son[x],topf);
        for(int e=fir[x];e;e=nex[e]){
            int v=to[e];
            if(v==fa[x]||v==son[x]) continue;
            dfs2(v,v);
        }
    }
    
    void pushup(int root){
        st[root].v=(st[root<<1].v+st[root<<1|1].v)%p;
    }
    
    void build(int root,int l,int r){
        st[root].l=l;st[root].r=r;
        if(l==r) st[root].v=wt[l];
        else{
            int m=l+r>>1;
            build(root<<1,l,m);build(root<<1|1,m+1,r);
            pushup(root);
        }
    }
    
    void pushdown(int root){
        st[root<<1].v=(st[root<<1].v+st[root].add*(st[root<<1].r-st[root<<1].l+1))%p;
        st[root<<1|1].v=(st[root<<1|1].v+st[root].add*(st[root<<1|1].r-st[root<<1|1].l+1))%p;
        st[root<<1].add=(st[root<<1].add+st[root].add)%p;
        st[root<<1|1].add=(st[root<<1|1].add+st[root].add)%p;
        st[root].add=0;
    }
    
    void change(int root,int l,int r,ll val){
        if(st[root].l>r||st[root].r<l) return ;
        if(st[root].l>=l&&st[root].r<=r){
            st[root].v=(st[root].v+val*(st[root].r-st[root].l+1))%p;
            st[root].add=(st[root].add+val)%p;
        }
        else{
            pushdown(root);
            change(root<<1,l,r,val);change(root<<1|1,l,r,val);
            pushup(root);
        }
    }
    
    ll query(int root,int l,int r){
        if(st[root].l>r||st[root].r<l) return 0;
        if(st[root].l>=l&&st[root].r<=r) return st[root].v;
        pushdown(root);
        return (query(root<<1,l,r)+query(root<<1|1,l,r))%p; 
    }
    
    void Chg(int x,int y,ll val){
        int f1=top[x],f2=top[y];
        while(f1!=f2){
            if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
            change(1,id[f1],id[x],val);
            x=fa[f1];f1=top[x];
        }
        if(dep[x]>dep[y]) swap(x,y);
        change(1,id[x],id[y],val);
    }
    
    ll Qry(int x,int y){
        int f1=top[x],f2=top[y];ll ans=0;
        while(f1!=f2){
            if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
            ans=(ans+query(1,id[f1],id[x]));
            x=fa[f1];f1=top[x];
        }
        if(dep[x]>dep[y]) swap(x,y);
        ans=(ans+query(1,id[x],id[y]))%p;
        return ans;
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n),read(m),read(r),read(p);
        for(int i=1;i<=n;i++) read(val[i]);
        for(int i=1;i<n;i++){
            int x,y;
            read(x),read(y);
            add(x,y);add(y,x);
        }
        dfs1(r,0,1);dfs2(r,r);build(1,1,n);
        while(m--){
            int op,x,y,z;
            read(op);
            if(op==1){
                read(x),read(y),read(z);
                Chg(x,y,z);
            }
            else if(op==2){
                read(x),read(y);
                printf("%lld
    ",Qry(x,y));
            }
            else if(op==3){
                read(x),read(y);
                change(1,id[x],id[x]+sz[x]-1,y);
            }
            else{
                read(x);
                printf("%lld
    ",query(1,id[x],id[x]+sz[x]-1));
            }
        }
        return 0;
    }
    View Code

    数据结构:

    树状数组

    单点加,区间和

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=500000+5;
    
    int a[maxn],c[maxn],n,m,op,x,y,k;
    
    template<typename T>void read(T& aa) {
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int lowbit(int x){return x&(-x);}
    
    int query(int x){
        int ans=0;
        while(x){
            ans+=c[x];x-=lowbit(x);
        }
        return ans;
    }
    
    void update(int x,int y){
        while(x<=n){
            c[x]+=y;x+=lowbit(x);
        }
    }
    
    int main(){
        read(n),read(m);
        for(int i=1;i<=n;i++){
            read(a[i]);
            update(i,a[i]);
        }
        while(m--){
            read(op);
            if(op==1){
                read(x),read(y);
                update(x,y);
            }
            else {
                read(x),read(y);
                printf("%d
    ",query(y)-query(x-1));
            }
        }
        return 0;
    }
    View Code

    区间加,单点查询

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=500000+5;
    
    int a[maxn],c[maxn],n,m,x,y,k,op,now;
    
    template<typename T>void read(T& aa) {
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int lowbit(int x){return x&(-x);}
    
    int query(int x){
        int ans=0;
        while(x){
            ans+=c[x];x-=lowbit(x);
        }
        return ans;
    }
    
    void update(int x,int y){
        while(x<=n){
            c[x]+=y;x+=lowbit(x);
        }
    }
    
    int main(){
        read(n),read(m);
        for(int i=1;i<=n;i++){
            read(a[i]);
            update(i,a[i]-now);
            now=a[i];
        }
        while(m--){
            read(op);
            if(op==1){
                read(x),read(y),read(k);
                update(x,k);update(y+1,-k);
            }
            else{
                read(x);
                printf("%d
    ",query(x));
            }
        }
        return 0;
    }
    View Code

    线段树

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=100000+50;
    
    int n,m,p;ll a[maxn];
    
    struct SegmentTree{int l,r;ll v,add,mul;}st[maxn<<2];
    
    void pushup(int root){
        st[root].v=(st[root<<1].v+st[root<<1|1].v)%p;
    }
    
    void build(int root,int l,int r){
        st[root].l=l;st[root].r=r;st[root].mul=1;
        if(l==r) st[root].v=a[l];
        else{
            int m=l+r>>1;
            build(root<<1,l,m);build(root<<1|1,m+1,r);
            pushup(root);
        }
    }
    
    void pushdown(int root){
        st[root<<1].v=(st[root<<1].v*st[root].mul+st[root].add*(st[root<<1].r-st[root].l+1))%p;
        st[root<<1|1].v=(st[root<<1|1].v*st[root].mul+st[root].add*(st[root<<1|1].r-st[root<<1|1].l+1))%p;
        st[root<<1].mul=st[root<<1].mul*st[root].mul%p;
        st[root<<1|1].mul=st[root<<1|1].mul*st[root].mul%p;
        st[root<<1].add=(st[root<<1].add*st[root].mul+st[root].add)%p;
        st[root<<1|1].add=(st[root<<1|1].add*st[root].mul+st[root].add)%p;
        st[root].add=0;st[root].mul=1;
    }
    
    void u1(int root,int l,int r,ll val){
        if(st[root].l>r||st[root].r<l) return ;
        if(st[root].l>=l&&st[root].r<=r){
            st[root].v=st[root].v*val%p;
            st[root].add=st[root].add*val%p;
            st[root].mul=st[root].mul*val%p;
        }
        else{
            pushdown(root);
            u1(root<<1,l,r,val);u1(root<<1|1,l,r,val);
            pushup(root);
        }
    }
    
    void u2(int root,int l,int r,ll val){
        if(st[root].l>r||st[root].r<l) return ;
        if(st[root].l>=l&&st[root].r<=r){
            st[root].v=(st[root].v+val*(st[root].r-st[root].l+1))%p;
            st[root].add=(st[root].add+val)%p;
        }
        else{
            pushdown(root);
            u2(root<<1,l,r,val);u2(root<<1|1,l,r,val);
            pushup(root);
        }
    }
    
    ll query(int root,int l,int r){
        if(st[root].l>r||st[root].r<l) return 0;
        if(st[root].l>=l&&st[root].r<=r) return st[root].v;
        pushdown(root);
        return (query(root<<1,l,r)+query(root<<1|1,l,r))%p;
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n),read(m),read(p);
        for(int i=1;i<=n;i++) read(a[i]);
        build(1,1,n);
        while(m--){
            int op,x,y;ll k;
            read(op),read(x),read(y);
            if(op==1){
                read(k);
                u1(1,x,y,k);
            }
            else if(op==2){
                read(k);
                u2(1,x,y,k);
            }
            else printf("%lld
    ",query(1,x,y));
        }
        return 0;
    }
    View Code

    权值线段树

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    #define ull unsigned long long
    #define maxx 2139062143
    #define maxint 2147483647
    using namespace std;
    
    const int maxn=100000+5;
    
    int T[4*maxn];
    int n,opt[maxn],a[maxn],ma[maxn],e,x;
    
    struct Data{
        int v,p;
    }t[maxn];
    
    bool cmp(const Data &a,const Data &b){
        return a.v<b.v;
    }
    
    int read(){
        int xx=0,kk=1;char ch;
        while(ch<'0'||ch>'9')  {if(ch=='-')kk=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
        return kk*xx;
    }
    
    void update(int root,int p,int v,int l,int r){//插入p时v==1,删除p时v==-1 
        T[root]+=v;
        if(l==r) return ;
        int m=(l+r>>1);
        if(p<=m) update(root*2,p,v,l,m);
        else update(root*2+1,p,v,m+1,r);
    }
    
    int kth(int root,int k,int l,int r){
        if(l==r) return l;
        int m=(l+r>>1);
        if(T[root*2]>=k) return kth(root*2,k,l,m);
        return kth(root*2+1,k-T[root*2],m+1,r);
    }
    
    int rank(int root,int p,int l,int r){
        if(r<p) return T[root];
        int m=(l+r>>1),res=0;
        res+=rank(root*2,p,l,m);
        if(m<p-1) res+=rank(root*2+1,p,m+1,r);
        return res;
    }
    
    int findp(int root,int l,int r){
        if(l==r) return l;
        int m=(l+r>>1);
        if(T[root*2+1]) return findp(root*2+1,m+1,r);
        return findp(root*2,l,m);
    }
    
    int pre(int root,int p,int l,int r){
        if(r<p){
            if(T[root]) return findp(root,l,r);
            return 0;
        }
        int m=(l+r)>>1,re;
        if(m<p-1&&T[root*2+1]&&(re=pre(root*2+1,p,m+1,r)))
        return re;
        return pre(root*2,p,l,m);
    }
    
    int findn(int root,int l,int r){
        if(l==r) return l;
        int m=(l+r)>>1;
        if(T[root*2]) return findn(root*2,l,m);
        return findn(root*2+1,m+1,r);
    }
    
    int nex(int root,int p,int l,int r){
        if(p<l){
            if(T[root]) return findn(root,l,r);
            return 0;
        }
        int m=(l+r)>>1,re;
        if(p<m&&T[root*2]&&(re=nex(root*2,p,l,m)))
        return re;
        return nex(root*2+1,p,m+1,r);
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            scanf("%d%d",&opt[i],&t[i].v);
            t[i].p=i;
        }
        sort(t+1,t+1+n,cmp);
        a[t[1].p]=++e; 
        ma[a[t[1].p]]=t[1].v;
        for(int i=2;i<=n;i++){
            if(t[i].v!=t[i-1].v) ++e;
            a[t[i].p]=e;
            ma[a[t[i].p]]=t[i].v;
        }
        for(int i=1;i<=n;i++){
            if(opt[i]==1) update(1,a[i],1,1,e);
            else if(opt[i]==2) update(1,a[i],-1,1,e);
            else if(opt[i]==3) printf("%d
    ",rank(1,a[i],1,e)+1);
            else if(opt[i]==4) printf("%d
    ",ma[kth(1,ma[a[i]],1,e)]);
            else if(opt[i]==5) printf("%d
    ",ma[pre(1,a[i],1,e)]);
            else printf("%d
    ",ma[nex(1,a[i],1,e)]);
        }
        return 0;
    }
    View Code

    RMQ

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=1e5+50;
    
    int n,m,ma[maxn][26];
    
    struct RMQ{
        int log2[maxn];
        void init(){
            for(int i=0;i<=n;i++) log2[i]=(i==0?-1:log2[i>>1]+1);
            for(int j=1;j<=20;j++)
            for(int i=1;i+(1<<j)-1<=n;i++) ma[i][j]=max(ma[i][j-1],ma[i+(1<<j-1)][j-1]);
        }
        int query(int ql,int qr){
            int k=log2[qr-ql+1];
            return max(ma[ql][k],ma[qr-(1<<k)+1][k]);
        }
    }rmq;
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n),read(m);
        for(int i=1;i<=n;i++) read(ma[i][0]);
        rmq.init();
        while(m--){
            int x,y;
            read(x),read(y);
            printf("%d
    ",rmq.query(x,y));
        }
        return 0;
    }
    View Code

    分块

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=500000+50;
    const int maxblo=1000;
    
    int bl[maxn],blo,n,a[maxn],m,sum[maxblo],tag[maxblo];
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n);read(m);
        blo=sqrt(n);
        for(int i=1;i<=n;i++){
            read(a[i]);
            bl[i]=(i-1)/blo+1;
            sum[bl[i]]+=a[i];
        }
        while(m--){
            int op,x,y;
            read(op),read(x),read(y);
            if(op==1){
                a[x]+=y;
                sum[bl[x]]+=y;
            }
            else{
                int ans=0;
                for(int i=bl[x]+1;i<=bl[y]-1;i++) ans+=sum[i];
                for(int i=x;i<=bl[x]*blo;i++) ans+=a[i];
                for(int i=(bl[y]-1)*blo+1;i<=y;i++) ans+=a[i];
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    View Code

    并查集

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=10000+50;
    const int maxm=200000+50;
    
    int n,m,fat[maxn];
    
    int father(int x){
        if(x!=fat[x]) fat[x]=father(fat[x]);
        return fat[x];
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(n),read(m);
        for(int i=1;i<=n;i++) fat[i]=i;
        while(m--){
            int x,y,op;
            read(op),read(x),read(y);
            int fa=father(x),fb=father(y);
            if(op==1){
                fat[fa]=fb;
            }
            else{
                if(fa==fb) cout<<"Y"<<endl;
                else cout<<"N"<<endl;
            }
        }
        return 0;
    }
    View Code

    数学:

    gcd / lcm

    int gcd(int a,int b){
        int c;
        while(a%b){
            c=a%b;
            a=b;
            b=c;
        }
        return b;
    }
    gcd
    int lcm(int a,int b){
        return a*b/gcd(a,b);
    }
    lcm

    快速幂

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    int b,p,mod;
    
    ll qsm(ll a,ll n){
        a%=mod;ll ans=1;
        for(ll i=n;i;i>>=1,a=(a*a)%mod)
        if(i&1) ans=(ans*a)%mod;
        return ans%mod;
    }
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        read(b),read(p),read(mod);
        cout<<b<<"^"<<p<<" mod "<<mod<<"="<<qsm(b,p)<<endl;
        return 0;
    }
    View Code

    快速乘

    O(logn)

    ll qsc(ll a,ll b,ll c){
        ll ans=0;
        a=a%c;
        b=b%c;
        while(b>0){
            if(b&1) ans=(ans+a)%c;
            a=(a+a)%c;
            b>>=1;
        }
        return ans;
    }
    View Code

    O(1)

    ll qsc(ll A,ll B,ll mod){
        return (A*B-(ll)((long double)A*B/mod)*mod+mod)%mod;
    }
    View Code

    中国剩余定理

    void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
        if(!b){
            d=a;x=1;y=0;
        }
        else exgcd(b,a%b,d,y,x),y-=x*(a/b);
    }
    
    ll china(int n,int *a,int *m){    // x ≡ a[ i ] ( mod m[ i ] )  
        ll M=1,d,y,x=0;
        for(int i=1;i<=n;i++) M*=m[i];
        for(int i=1;i<=n;i++){
            ll w=M/m[i];
            exgcd(m[i],w,d,d,y);
            x=(x+y*w*a[i])%M;
        }
        return (x+M)%M;
    }
    View Code

    线性筛素数

    bool v[1000010];
    memset(v,1,sizeof(v));v[0]=v[1]=0;
    int prime[1000010],tot=0;
    for(int i=2;i<=limit;i++){
        if(v[i]) prime[++tot]=i;
        for(int j=1;j<=tot&&i*prime[j]<=limit;j++){
            v[prime[j]*i]=0;
            if(i%prime[j]==0) break;
        }
    }
    View Code

    根号n判素数

    bool pd(int x){
        if(x==0||x==1) return false;
        for(int i=2;i*i<=x;i++)
        if(x%i==0) return false;
        return true;
    }
    普通版
    bool pd(int x){
        if(x==0||x==1||x==4) return false;
        if(x==2||x==3) return true;
        if(x%6!=1&&x%6!=5) return false;
        if(x%2==0||x%3==0) return false;
        for(int i=5;i*i<=x;i+=6) 
        if(x%i==0||x%(i+2)==0) return false;
        return true;
    }
    小优化

    线性筛欧拉函数

    void sphi(int limit){
        phi[1]=1;
        for(int i=2;i<=limit;i++){
            if(!a[i]) prime[++tot]=i,phi[i]=i-1;
            for(int j=1;j<=tot&&i*prime[j]<=limit;j++){
                a[i*prime[j]]=1;
                if(i%prime[j]==0){
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
    View Code

    根号n求欧拉函数

    ll PHI(ll x){
        ll ret=x;
        for(ll i=2;i*i<=x;i++)
        if(x%i==0){
            ret=ret-ret/i;
            while(x%i==0) x/=i;
        }
        if(x>1) ret=ret-ret/x;
        return ret;
    }
    View Code

    基础算法

    归并排序

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    const int maxn=5e5+50;
    
    int c[maxn],d[maxn],n;ll ans;
    
    void merge_sort(int l,int r){
        if(l==r) return ;
        int mid=l+r>>1,i,j,k;
        merge_sort(l,mid);merge_sort(mid+1,r);
        i=k=l;j=mid+1;
        while(i<=mid&&j<=r){
            if(c[i]<=c[j]) d[k++]=c[i++];
            else ans+=mid-i+1,d[k++]=c[j++];
        }
        while(i<=mid) d[k++]=c[i++];
        while(j<=r) d[k++]=c[j++];
        for(int i=l;i<=r;i++) c[i]=d[i];
    }
    
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++) cin>>c[i];
        merge_sort(1,n);
        cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    字符串匹配算法
    C#中窗体的位置和大小
    关于C#值类型,引用类型,值传递,引用传递(转载)
    ArcMap中设置.mxd相对路径
    统计学上的知识
    .NET 数学实现资料(ZZ)
    牛腩新闻系统学习笔记06讲 编写SQLHelper
    DropDownList 控件不能触发SelectedIndexChanged 事件的另一个原因
    牛腩新闻视频 03讲 数据库设计的心得 如何建立外键sql2008的数据库关系图功能
    使用sql server management studio 2008 连接数据库,无法查看数据库,提示 无法为该请求检索数据 错误916
  • 原文地址:https://www.cnblogs.com/rlddd/p/9898601.html
Copyright © 2011-2022 走看看