zoukankan      html  css  js  c++  java
  • 模板整理

    RT

    有些代码写的时间很长了,会有一些错误或者非常XX的写法。。。还有很多算法不全。。。有空更新

    P3385 【模板】负环

    题目描述

    暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索

    输入输出格式

    输入格式:

    第一行一个正整数T表示数据组数,对于每组数据:

    第一行两个正整数N M,表示图有N个顶点,M条边

    接下来M行,每行三个整数a b w,表示a->b有一条权值为w的边(若w<0则为单向,否则双向)

    输出格式:

    共T行。对于每组数据,存在负环则输出一行"YE5"(不含引号),否则输出一行"N0"(不含引号)。

    输入输出样例

    输入样例#1: 
    2
    3 4
    1 2 2
    1 3 4
    2 3 1
    3 1 -3
    3 3
    1 2 3
    2 3 4
    3 1 -8
    
    输出样例#1: 
    N0
    YE5
    

    说明

    nleq 2000n200mleq 3000m3000-10000leq wleq 1000010000w10000Tleq

    code

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    const int INF = 10000;
    const int MAXN = 30000;
    int T, n, m;
    int head[MAXN * 2], tot = 0;
    int dis[MAXN], cnt[MAXN];
    bool vis[MAXN];
    
    struct Edge {
        int node, next, value;
    }e[MAXN];
    
    inline int read() {
        int num = 0, f = 1; char ch = getchar();
        while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
        while (isdigit(ch)) { num = num * 10 + ch - '0'; ch = getchar(); }
        return num * f;
    }
    
    void Add_Edge(int x, int y, int w) {
        e[++tot].node = y; e[tot].value = w; e[tot].next = head[x]; head[x] = tot;
    } 
    
    bool SPFA(int s) {
        queue<int> q;
        memset(dis, INF, sizeof(dis));
        memset(vis, false, sizeof(vis));
        memset(cnt, 0, sizeof(cnt));
        dis[s] = 0;
        vis[s] = true;
        cnt[s] = 1;
        q.push(s);
        while (!q.empty()) {
            int h = q.front();
            q.pop();
            vis[h] = false;
            for (int i = head[h], v; ~i, v = e[i].node; i = e[i].next) {
                if (dis[h] + e[i].value < dis[v]) {
                    if (++ cnt[v] >= n) return true;
                    dis[v] = dis[h] + e[i].value;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = true;
                    }
                }
            } 
        }
        return false;
    }
    
    int main() { 
        T = read();
        while (T --) {
            tot = 0;
            memset(head, -1, sizeof(head));
            n = read(); m = read();
            for (int i = 1; i <= m; ++ i) {
                int x = read(), y = read(), w = read();
                Add_Edge(x, y, w);
                if (w >= 0) Add_Edge(y, x, w);
            }
            if(SPFA(1)) printf("YE5
    ");
            else printf("N0
    ");
        }
        return 0;
    } 

    P3387 【模板】缩点

    题目背景

    缩点+DP

    题目描述

    给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。

    允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。

    输入输出格式

    输入格式:

    第一行,n,m

    第二行,n个整数,依次代表点权

    第三至m+2行,每行两个整数u,v,表示u->v有一条有向边

    输出格式:

    共一行,最大的点权之和。

    输入输出样例

    输入样例#1: 
    2 2
    1 1
    1 2
    2 1
    输出样例#1: 
    2

    说明

    n<=10^4,m<=10^5,点权<=1000

    算法:Tarjan缩点+DAGdp

    code

    某同学的毒瘤代码

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    
    const int Max = (int)1e9 + 7;
    const int MaxnEdge = (int)1e5 + 5;
    const int MaxnVertex = (int)1e4 + 5;
    
    int Cnt,MergeCnt;
    int Head[MaxnVertex],MergeHead[MaxnVertex];
    struct Graph{
        int Vertex;
        int Next;
    }Edge[MaxnEdge],MergeEdge[MaxnVertex];
    int VertexN[MaxnVertex],MergeVertexN[MaxnVertex];
    
    int DFSN[MaxnVertex],Lowest[MaxnVertex];
    int Top,Stack[MaxnVertex];
    bool InStack[MaxnVertex];
    int Time;
    
    bool IsNotZero[MaxnVertex];
    int Link[MaxnEdge];
    int MergeVertex;
    
    int H,T;
    int Queue[MaxnVertex];
    bool Visited[MaxnVertex];
    int Dis[MaxnVertex];
    
    int Ans;
    
    int N,M;
    
    void Insert(int From,int To,int &TmpCnt,int *TmpHead,Graph *TmpEdge){
        TmpEdge[++ TmpCnt].Next = TmpHead[From];
        TmpEdge[TmpCnt].Vertex = To;
        TmpHead[From] = TmpCnt;
    }
    
    void Tarjan(int X){
        DFSN[X] = Lowest[X] = ++Time;
        Stack[++ Top] = X;
        InStack[X] = true;
    
        int TmpV; // TmpVertex
        for(int i = Head[X];i;i = Edge[i].Next){
            TmpV = Edge[i].Vertex;
            if(InStack[TmpV]) Lowest[X] = std::min(Lowest[X], DFSN[TmpV]);
            else if (!DFSN[TmpV]) Tarjan(TmpV), Lowest[X] = std::min(Lowest[X], Lowest[TmpV]); 
            /*if(!DFSN[TmpV]){
                Tarjan(TmpV);
                Lowest[X] = std::min(Lowest[X],Lowest[TmpV]);
            } else if(InStack[TmpV])
                Lowest[X] = std::min(Lowest[X],Lowest[TmpV]);*/
        }
        /*if(DFSN[X] == Lowest[X]){
            ++ MergeVertex;
            TmpV = Stack[-- Top];
            while(TmpV != X){
                Link[TmpV] = MergeVertex;
                InStack[TmpV] = false;
                MergeVertexN[MergeVertex] += VertexN[TmpV];
                TmpV = Stack[-- Top];
            }
        }*/
        if(DFSN[X] == Lowest[X]){
            ++ MergeVertex;
            TmpV = Stack[Top];
            while(TmpV != X){
                Link[TmpV] = MergeVertex;
                InStack[TmpV] = false;
                MergeVertexN[MergeVertex] += VertexN[TmpV];
                TmpV = Stack[-- Top];
            }
            Link[TmpV] = MergeVertex;
            InStack[TmpV] = false;
            MergeVertexN[MergeVertex] += VertexN[TmpV];
            TmpV = Stack[-- Top];
        }
    }
    
    void Merge(){
        int TmpV; //TmpVertex
        for(int i = 1;i <= N;++ i){
            for(int j = Head[i];j;j = Edge[j].Next){
                TmpV = Edge[j].Vertex;
                if(Link[TmpV] != Link[i]){
                    IsNotZero[Link[TmpV]] = true;
                    Insert(Link[i],Link[TmpV],MergeCnt,MergeHead,MergeEdge);
                }
            }
        }
    }
    
    void SPFA(int X){
        memset(Queue,0,sizeof(Queue));
        memset(Dis,0,sizeof(Dis));
        memset(Visited,0,sizeof(Visited));
        H = T = 0;
        Queue[++ T] = X;
        Visited[X] = true;
        Dis[X] = MergeVertexN[X];
        int TmpV,TmpVT,TmpSum; //TmpVertex,TmpVerteTo
        while(H != T){
            H = (H + 1) % MaxnVertex;
            TmpV = Queue[H];
            Visited[TmpV] = false;
            for(int i = MergeHead[TmpV];i;i = MergeEdge[i].Next){
                TmpVT = MergeEdge[i].Vertex;
                TmpSum = Dis[TmpV] + MergeVertexN[TmpVT];
                if(Dis[TmpVT] < TmpSum){
                    Dis[TmpVT] = TmpSum;
                    if(!Visited[TmpVT]){
                        T = (T + 1) % MaxnVertex;
                        Queue[T] = TmpVT;
                        Visited[TmpVT] = true;
                    }
                }
            }
        }
        for(int i = 1;i <= N;++ i)
        //for(int i = 1;i <= MergeVertex;++ i)
            Ans = std::max(Ans,Dis[i]);
            
    }
    
    void Read(){
        scanf("%d%d",&N,&M);
        for(int i = 1;i <= N;++ i)
            scanf("%d",&VertexN[i]);
        int TmpX,TmpY;
        for(int i = 1;i <= M;++ i){
            scanf("%d%d",&TmpX,&TmpY);
            Insert(TmpX,TmpY,Cnt,Head,Edge);
        }
    }
    
    int main(){
        Read();
        for(int i = 1;i <= N;++ i)
            if(!DFSN[i])
                Tarjan(i);
        Merge();
        for(int i = 1;i <= MergeVertex;++ i)
            if(!IsNotZero[i])
                SPFA(i);
        printf("%d",Ans);
        return 0;
    }

    mine

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    const int MAXN = 100010;
    
    int n,m,x,y,ans;
    int tot,head[MAXN]; 
    int bc; 
    int cnt; 
    int top;
    int dfn[MAXN]; 
    int low[MAXN]; 
    int num[MAXN]; 
    int col[MAXN];
    int vis[MAXN];
    int stack[MAXN];
    int a[MAXN];
    int dis[MAXN];
    int linkx[MAXN], linky[MAXN];
    
    struct Edge {
        int node,next,value;
    }e[MAXN];
    
    inline int read() {
        int num = 0, f = 1; char ch = getchar();
        while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
        while (isdigit(ch)) { num = num * 10 + ch - '0'; ch = getchar(); }
        return num * f; 
    }
    
    void Add_Edge(int x,int y) {
        e[++tot].next = head[x]; e[tot].node = y; head[x] = tot;
    }
    
    void tarjan(int x) {
        dfn[x] = low[x] = ++cnt;
        stack[++top] = x; 
        vis[x] = 1;
        for (int i = head[x],v; v = e[i].node,i; i = e[i].next) {
            if (vis[v]) low[x] = min(low[x], dfn[v]);
            else if (!dfn[v]) tarjan(v), low[x] = min(low[x], low[v]);
        }
        if (low[x] == dfn[x]) {
            ++bc; 
            vis[x] = 0;
            while (stack[top+1] != x) {
                col[stack[top]] = bc; 
                num[bc] += a[stack[top]];
                vis[stack[top]] = 0;
                top--;
             }
        }
    }
    
    void SPFA(int x) {
        memset(dis, 0, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        queue<int> que;
        dis[x] = num[x];
        vis[x] = 1;
        que.push(x);
        while (!que.empty()) {
            int h = que.front();
            vis[h] = 0;
            que.pop();
            for (int i = head[h]; i ; i = e[i].next) {
                int v = e[i].node;
                if (dis[v] < dis[h] + num[v]) {
                    dis[v] = dis[h] + num[v];
                    if (!vis[v]) { vis[v] = 1; que.push(v); }
                }
            }
        } 
        for (int i = 1; i <= bc; ++ i) ans = max(ans, dis[i]);
    }
    
    int main() {
        n = read(); m = read();
        for (int i = 1; i <= n; ++ i) a[i] = read();
        for (int i = 1; i <= m; ++ i) {
            x = read(); y = read();
            Add_Edge(x,y);
            linkx[i] = x; linky[i] = y;
        }
        for (int i = 1; i <= n; ++ i) if (!dfn[i]) tarjan(i);
        memset(head, 0, sizeof(head));
        memset(e, 0, sizeof(e));
        for (int i = 1; i <= m; ++ i) 
            if (col[linkx[i]] != col[linky[i]]) Add_Edge(col[linkx[i]], col[linky[i]]);
        for (int i = 1; i <= bc; ++ i) SPFA(i);
        cout << ans << endl;
        return 0;
    }

    并差集

    //_查询
    //路径压缩
    int find(int i) {
        if (fa[i] != i) fa[i] = find(fa[i]);
        return fa[i];
    }
    
    //简单合并
    bool unionSet(int far, int son) {
        int a = find(far);
        int b = find(son);
        if (a == b) return false;
        fa[b] = a;
        cnt[a] += cnt[b];
        return true;
    }
     
    //_按秩合并
    //没怎么用过,一般路径压缩就够了。copy by 某大佬
    int rank[N] = {0};
    bool _unionSet(int x, int y) {
        int a = find(x);
        int b = find(y);
        if (a == b) return false;
        if (rank[a] > rank[b]) {
            fa[b] = a; 
            cnt[a] += cnt[b];
        }
        else {
            fa[a] = b; 
            cnt[b] += cnt[a];
            if (rank[a] == rank[b])
                rank[b]++; 
        }
        return true;
    }

    乘法逆元

    typedef long long ll;
    
    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 inv(ll a, ll p) {
        ll d, x, y;
        exgcd(a, p, d, x, y);
        return d == 1 ? (x + p) % p : -1;
    }

    P3388 【模板】割点(割顶)

    题目背景

    割点

    题目描述

    给出一个n个点,m条边的无向图,求图的割点。

    输入输出格式

    输入格式:

    第一行输入n,m

    下面m行每行输入x,y表示x到y有一条边

    输出格式:

    第一行输出割点个数

    第二行按照节点编号从小到大输出节点,用空格隔开

    输入输出样例

    输入样例#1: 
    6 7
    1 2
    1 3
    1 4
    2 5
    3 5
    4 5
    5 6
    输出样例#1: 
    1 
    5

    说明

    n,m均为100000

    tarjan 图不一定联通!!!

    code

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #define MAXN 200010
    
    using namespace std;
    
    int n,m,cnt,head[MAXN],dfn[MAXN],low[MAXN],stack[MAXN],top,num,nums,ID,ans;
    bool vis[MAXN],poi[MAXN],cut[MAXN];
    
    struct Edge {
        int next,node,value;
    }e[MAXN];
    
    void add(int u,int v) {
        e[++cnt].node = v;
        e[cnt].next = head[u];
        head[u] = cnt;
    }
    
    void tarjan(int x,int father) {
        int son = 0;
        dfn[x] = low[x] = ++ID;
        for (int i = head[x] , v ; v = e[i].node , i ; i = e[i].next) {
            if (!dfn[v]) {
                tarjan(v,father);
                low[x] = min(low[x],low[v]);
                if (low[v] >= dfn[x] && x != father) cut[x] = true;
                else if (x == father) son++;
            }
            low[x] = min(low[x],dfn[v]);
        }
        if (x == father && son >= 2) cut[father] = true;  
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        while (m--) {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y); add(y,x);
        }
        for (int i = 1; i <= n; i++) 
            if (!dfn[i]) tarjan(i,i);
        for (int i = 1; i <= n; i++) 
            if (cut[i]) ans++;
        printf("%d
    ",ans);
        for (int i = 1; i <= n; i++)
            if (cut[i]) printf("%d ",i);
        return 0;
    } 

    P3384 【模板】树链剖分

    题目描述

    如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作:

    操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z

    操作2: 格式: 2 x y 表示求树从x到y结点最短路径上所有节点的值之和

    操作3: 格式: 3 x z 表示将以x为根节点的子树内所有节点值都加上z

    操作4: 格式: 4 x 表示求以x为根节点的子树内所有节点值之和

    输入输出格式

    输入格式:

    第一行包含4个正整数N、M、R、P,分别表示树的结点个数、操作个数、根节点序号和取模数(即所有的输出结果均对此取模)。

    接下来一行包含N个非负整数,分别依次表示各个节点上初始的数值。

    接下来N-1行每行包含两个整数x、y,表示点x和点y之间连有一条边(保证无环且连通)

    接下来M行每行包含若干个正整数,每行表示一个操作,格式如下:

    操作1: 1 x y z

    操作2: 2 x y

    操作3: 3 x z

    操作4: 4 x

    输出格式:

    输出包含若干行,分别依次表示每个操作2或操作4所得的结果(对P取模)

    输入输出样例

    输入样例#1: 
    5 5 2 24
    7 3 7 8 0 
    1 2
    1 5
    3 1
    4 1
    3 4 2
    3 2 2
    4 5
    1 5 1 3
    2 1 3
    输出样例#1: 
    2
    21

    说明

    时空限制:1s,128M

    数据规模:

    对于30%的数据: N leq 10, M leq 10N10,M10

    对于70%的数据: N leq {10}^3, M leq {10}^3N103,M103

    对于100%的数据: N leq {10}^5, M leq {10}^5N105,M105

    code

    不太会了已经QwQ

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
     
    using namespace std;
    
    const int MAXN = 2 * 1e6 + 10;
    int cnt = 0, head[MAXN * 2];
    int n, m, root, MOD, tim = 0, a[MAXN], b[MAXN];
    int dep[MAXN], fat[MAXN], son[MAXN], tot[MAXN], top[MAXN], idx[MAXN];
    
    struct Edge {
        int node, next;
    }e[MAXN];
    
    struct Tree {
        int lef, rig, wei, siz, tag;
    }t[MAXN];
    
    inline int read() {
        int num = 0, f = 1;
        char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') f = -1; 
            ch = getchar();
        }
        while (isdigit(ch)) {
            num = num * 10 + ch - '0';
            ch = getchar();
        } return num * f;
    }
    
    void add_edge(int x, int y) {
        e[++cnt].next = head[x]; head[x] = cnt; e[cnt].node = y; 
        e[++cnt].next = head[y]; head[y] = cnt; e[cnt].node = x; 
    }
    
    void update(int u) {
        t[u].wei = (t[u << 1].wei + t[u << 1 | 1].wei + MOD) % MOD;
    }
    
    void build(int u, int l, int r) {
        int lu = u << 1, ru = u << 1 | 1, mid = (l + r) >> 1;
        t[u].lef = l; t[u].rig = r; t[u].siz = r - l + 1;
        if (l == r) {
            t[u].wei = a[l];
            return ;
        }
        build(lu, l, mid); build(ru, mid + 1, r);
        update(u);
    }
    
    int dfs1(int now, int fa, int de) {
        dep[now] = de;
        fat[now] = fa;
        tot[now] = 1;
        int maxson = -1;
        for (int i = head[now]; i ; i = e[i].next) {
            if (e[i].node == fa) continue;
            tot[now] += dfs1(e[i].node, now, de + 1);
            if (tot[e[i].node] > maxson)
                maxson = tot[e[i].node], son[now] = e[i].node; 
        }
        return tot[now];
    }
    
    void dfs2(int now, int topf) {
        idx[now] = ++tim;
        a[tim] = b[now];
        top[now] = topf;
        if (!son[now]) return ;
        dfs2(son[now], topf);
        for (int i = head[now]; i ; i = e[i].next)
            if (!idx[e[i].node])
                dfs2(e[i].node, e[i].node); 
    }
    
    void pushdown(int u) {
        int lu = u << 1, ru = u << 1 | 1;
        if (!t[u].tag) return ;
        t[lu].wei = (t[lu].wei + t[lu].siz * t[u].tag) % MOD;
        t[ru].wei = (t[ru].wei + t[ru].siz * t[u].tag) % MOD;
        t[lu].tag = (t[lu].tag + t[u].tag) % MOD;
        t[ru].tag = (t[ru].tag + t[u].tag) % MOD;
        t[u].tag = 0;
    }
    
    void IntervalAdd(int u, int l, int r, int v) {
        int lu = u << 1, ru = u << 1 | 1, mid = (t[u].lef + t[u].rig) >> 1;
        if (l <= t[u].lef && t[u].rig <= r) {
            t[u].wei += t[u].siz * v;
            t[u].tag += v;
            return ; 
        }
        pushdown(u);
        if (l <= mid) IntervalAdd(lu, l, r, v);
        if (r > mid)  IntervalAdd(ru, l, r, v);
        update(u);
    }
    
    void TreeAdd(int x, int y, int v) {
        while (top[x] != top[y]) {
            if (dep[top[x]] < dep[top[y]]) swap(x, y);
            IntervalAdd(1, idx[top[x]], idx[x], v);
            x = fat[top[x]];
        }
        if (dep[x] > dep[y]) swap(x, y);
        IntervalAdd(1, idx[x], idx[y], v);
    } 
    
    int IntervalSum(int u, int l, int r) {
        int ans = 0, lu = u << 1, ru = u << 1 | 1, mid = (t[u].lef + t[u].rig) >> 1;
        if (l <= t[u].lef && t[u].rig <= r) return t[u].wei;
        pushdown(u);
        if (l <= mid) ans = (ans + IntervalSum(lu, l, r)) % MOD;
        if (r > mid)  ans = (ans + IntervalSum(ru, l, r)) % MOD;
        return ans;
    }
    
    void TreeSum(int x, int y) {
        int ans = 0;
        while (top[x] != top[y]) {
            if (dep[top[x]] < dep[top[y]]) swap(x, y);
            ans = (ans + IntervalSum(1, idx[top[x]], idx[x])) % MOD;
            x = fat[top[x]];
        }
        if (dep[x] > dep[y]) swap(x, y);
        ans = (ans + IntervalSum(1, idx[x], idx[y])) % MOD;
        printf("%d
    ", ans);
    }
    
    int main() {
        memset(head, 0, sizeof (head));
        n = read(); m = read(); root = read(); MOD = read();
        for (int i = 1; i <= n; i++) b[i] = read();
        for (int i = 1; i <= n - 1; i++) {
            int x = read(), y = read();
            add_edge(x, y);
        }
        dfs1(root, 0, 1); dfs2(root, root);
        build(1, 1, n);
        while (m--) {
            int x, y, z, kind = read();
            if (kind == 1) {
                x = read(); y = read(); z = read(); z = z % MOD;
                TreeAdd(x, y, z);
            }
            else if (kind == 2) {
                x = read(); y = read();
                TreeSum(x, y);
            }
            else if (kind == 3) {
                x = read(); z = read();
                IntervalAdd(1, idx[x], idx[x] + tot[x] - 1, z % MOD);
            }
            else if (kind == 4) {
                x = read();
                printf("%d
    ", IntervalSum(1, idx[x], idx[x] + tot[x] - 1));
            }
        }
        return 0;
    }

    P3374 【模板】树状数组 1

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某一个数加上x

    2.求出某区间每一个数的和

    输入输出格式

    输入格式:

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3个整数,表示一个操作,具体如下:

    操作1: 格式:1 x k 含义:将第x个数加上k

    操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

    输出格式:

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入样例#1: 
    5 5
    1 5 4 2 3
    1 1 3
    2 2 5
    1 3 -1
    1 4 2
    2 1 4
    输出样例#1: 
    14
    16

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=10000,M<=10000

    对于100%的数据:N<=500000,M<=500000

    code

    #include<iostream>
    #include<cstdio>
    #define INT register int 
    
    using namespace std;
    
    const int MAXN = 5e5 + 5;
    int n, m, a[MAXN];
    char ss[1<<17], *A = ss, *B = ss;
    
    char sr[20], z[20]; 
    int C = -1, Z;
    
    inline void updata(int pos,int x) { 
        while (pos <= n) { 
            a[pos] += x; 
            pos += (-pos) & pos; 
        } 
    }
    
    inline int query(int pos) { 
        int ans = 0; 
        while(pos) { 
            ans += a[pos]; 
            pos -= (-pos) & pos;
        } 
        return ans;
    }
    
    int main(){
        scanf("%d%d", &n, &m);
        for (INT i = 1; i <= n; ++ i) {
            int x; 
            scanf("%d", &x);
            updata(i, x);
        }
        for (INT i = 1; i <= m; ++ i) {
            int opt, l, r;
            scanf("%d%d%d", &opt, &l, &r);
            if (opt == 1) updata(l, r);
            else printf("%d
    ", query(r) - query(l - 1));
        }
        return 0;
    }

    P3390 【模板】矩阵快速幂

    题目背景

    矩阵快速幂

    题目描述

    给定n*n的矩阵A,求A^k

    输入输出格式

    输入格式:

    第一行,n,k

    第2至n+1行,每行n个数,第i+1行第j个数表示矩阵第i行第j列的元素

    输出格式:

    输出A^k

    共n行,每行n个数,第i行第j个数表示矩阵第i行第j列的元素,每个元素模10^9+7

    输入输出样例

    输入样例#1: 
    2 1
    1 1
    1 1
    输出样例#1: 
    1 1
    1 1

    说明

    n<=100, k<=10^12, |矩阵元素|<=1000 算法:矩阵快速幂

    code

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    const LL mod=1000000007;
    
    int n; LL m;
    
    struct Matrix {
        LL a[105][105];
        Matrix operator * (const Matrix &x) const {
            Matrix res;
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= n; j++) {
                    res.a[i][j] = 0;
                    for (int k = 1; k <= n; k++)
                        res.a[i][j] = (res.a[i][j] + a[i][k] * x.a[k][j]) % mod;
                }
            return res;
        }
    }x,ans;
    
    int main() {
        scanf("%d%lld",&n,&m);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                scanf("%lld",&x.a[i][j]);
        ans = x, m--;
        while (m) {
            while ((m & 1LL) == 0) 
                x = x * x,m >>= 1LL;
            ans = ans * x; m >>= 1LL; x = x * x; 
        }
        for (int i = 1; i <= n; i++) {
            printf("%lld",ans.a[i][1]);
            for (int j = 2; j <= n; j++)
                printf(" %lld",ans.a[i][j]);
            printf("
    ");
        }
        return 0;
    }

    P3382 【模板】三分法

    题目描述

    如题,给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减。试求出x的值。

    输入输出格式

    输入格式:

    第一行一次包含一个正整数N和两个实数l、r,含义如题目描述所示。

    第二行包含N+1个实数,从高到低依次表示该N次函数各项的系数。

    输出格式:

    输出为一行,包含一个实数,即为x的值。四舍五入保留5位小数。

    输入输出样例

    输入样例#1: 
    3 -0.9981 0.5
    1 -3 -3 1
    输出样例#1: 
    -0.41421

    说明

    时空限制:50ms,128M

    数据规模:

    对于100%的数据:7<=N<=13

    样例说明:

    如图所示,红色段即为该函数f(x)=x^3-3x^2-3x+1在区间[-0.9981,0.5]上的图像。

    当x=-0.41421时图像位于最高点,故此时函数在[l,x]上单调增,[x,r]上单调减,故x=-0.41421,输出-0.41421。

    (Tip.l&r的范围并不是非常大ww不会超过一位数)

    code

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    const int MAXN = 15;
    int n;
    double a[MAXN];
    
    double F(double x) {
        double Sum = 0;
        for (int i = n; i >= 0; -- i) Sum = Sum * x + a[i];
        return Sum;
    }
    
    int main() {
        double L, R;
        cin >> n >> L >> R;
        for (int i = n; i >= 0; -- i) cin >> a[i];
        for (int i = 0; i < 100; ++ i) {
            double m1 = L + (R - L) / 3.0;
            double m2 = R - (R - L) / 3.0;
            if (F(m1) > F(m2)) R = m2; 
            else L = m1;
        }
        printf("%.5lf
    ", L);
        return 0;
    } 

    P3386 【模板】二分图匹配

    题目背景

    二分图

    感谢@一扶苏一 提供的hack数据 (没错这就是ZAY大佬

    题目描述

    给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数

    输入输出格式

    输入格式:

    第一行,n,m,e

    第二至e+1行,每行两个正整数u,v,表示u,v有一条连边

    输出格式:

    共一行,二分图最大匹配

    输入输出样例

    输入样例#1: 
    1 1 1
    1 1
    输出样例#1: 
    1

    说明

    n,m leq 1000n,m1000 , 1 leq u leq n1un , 1 leq v leq m1vm

    因为数据有坑,可能会遇到 v>mv>m 的情况。请把 v>mv>m 的数据自觉过滤掉。

    算法:二分图匹配

    code

    匈牙利

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    
    const int N = 1e3;
    bool f[N][N], vis[N];
    int n, m, e, match[N];
    
    inline int read() {
        int num = 0, f = 1; char ch = getchar();
        while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
        while (ch >= '0' && ch <= '9') { num = num * 10 + ch - '0'; ch = getchar(); }
        return num * f;
    }
    
    bool dfs(int pos) {
        for (int i = 1; i <= m; ++ i) {
            if (f[pos][i] && !vis[i]) {
                vis[i] = true;
                if (!match[i] || dfs(match[i])) {
                /*如果这个点i还未匹配则pos和他匹配,如果这个点已经匹配,
                那么如果本来和他匹配的点match[i]还能找到另一个点匹配则pos把i“抢”过来,
                让match[i]去匹配另一个点,否则就不干涉i和match[i]匹配*/
                    match[i] = pos;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main() {
        n = read(); m = read(); e = read();
        for (int i = 1; i <= e; ++ i) {
            int x = read(), y = read();
            if (x <= n && y <= m) f[x][y] = true;
        }
        int ans = 0;
        for (int i = 1; i <= n; ++ i) {
            memset(vis, 0, sizeof(vis));
            if (dfs(i)) ans++;
        }
        printf("%d
    ", ans);
    }

    DINIC

    (脑子一抽写成了class QwQ。。。懒得改了)

    #prag
    ma GCC optimize("O8")
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    const int N = 2010;
    const int M = 1000010;
    const int INF = 0x7fffffff;
    
    class MAXFLOW {
        public:        
            void init() {
                int n1 = read(), n2 = read(), m0 = read(); m = 0;
                n = n1 + n2 + 2;
                for (int i = 1; i <= m0; ++ i) {
                    int x = read(), y = read();
                    if (x <= n1 && y <= n2) {
                        Add_Edge(x + 1, y + n1 + 1, 1, m + 2);
                        Add_Edge(y + n1 + 1, x + 1, 0, m);
                    }
                }
                for (int i = 1; i <= n1; ++ i) {
                    Add_Edge(1,i + 1, 1, m + 2);
                    Add_Edge(i + 1, 1, 0, m);
                }
                for (int i = 1; i <= n2; ++ i) {
                    Add_Edge(i + n1 + 1, n, 1, m + 2);
                    Add_Edge(n, i + n1 + 1, 0, m);
                }
                s = 1; t = n;
            }
            
            void doit() {
                printf("%d
    ",DINIC());
            }
            
            bool bfs() {
                while (!que.empty()) que.pop();
                memset(dep, 0, sizeof(dep));
                que.push(s);
                dep[s] = 1;
                while (!que.empty()) {
                    int h = que.front(); 
                    que.pop();
                    for (int i = head[h], v; i, v = e[i].node; i = e[i].next) {
                        if (e[i].value > 0 && !dep[v]) {
                            dep[v] = dep[h] + 1;
                            que.push(v);
                        }
                    }
                }
                if (dep[t]) return true;
                return false;
            }
    
            int dfs(int pos, int cur) {
                if (pos == t) return cur;
                int rst = cur;
                for (int i = head[pos], v; i, v = e[i].node; i = e[i].next) {
                    if (dep[v] == dep[pos] + 1 && e[i].value > 0 && rst) {
                        int flow = dfs(v, std::min(e[i].value, rst));
                        if (flow > 0) {
                            e[i].value -= flow;
                            rst -= flow;
                            e[e[i].rev].value += flow;
                        }
                    }
                }
                return cur - rst;
            }
    
            int DINIC() {
                int ans = 0;
                while (bfs()) ans += dfs(s, INF);
                return ans;
            }
            
        private:
            int n, m, s, t, dep[N], head[N];
            std::queue<int> que;
            
            struct Edge {
                int node,value,next,rev;
            } e[M<<1];
            
            inline int read() {
                int num = 0, f = 1; char ch = getchar();
                while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
                while (ch >= '0' && ch <= '9') { num = (num << 3) + (num << 1) + (ch ^ 48); ch = getchar(); }
                return num * f;
            }
            
            inline void Add_Edge(int x,int y,int v,int rev) {
                e[++m].node = y; e[m].value = v; e[m].rev = rev; 
                e[m].next = head[x]; head[x] = m;
            }
    } Maxflow;
    
    int main() {
        Maxflow.init();
        Maxflow.doit();
        return 0;
    }

    P3375 【模板】KMP字符串匹配

    题目描述

    如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。

    为了减少骗分的情况,接下来还要输出子串的前缀数组next。

    (如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。)

    输入输出格式

    输入格式:

    第一行为一个字符串,即为s1

    第二行为一个字符串,即为s2

    输出格式:

    若干行,每行包含一个整数,表示s2在s1中出现的位置

    接下来1行,包括length(s2)个整数,表示前缀数组next[i]的值。

    输入输出样例

    输入样例#1: 
    ABABABC
    ABA
    输出样例#1: 
    1
    3
    0 0 1 
    

    说明

    时空限制:1000ms,128M

    数据规模:

    设s1长度为N,s2长度为M

    对于30%的数据:N<=15,M<=5

    对于70%的数据:N<=10000,M<=100

    对于100%的数据:N<=1000000,M<=1000000

    样例说明:

    所以两个匹配位置为1和3,输出1、3

    code

    #include<cstdio> 
    #include<cstring>
    
    using namespace std;
    
    char a1[2000000],a2[2000000];
    int kmp[2000000];
    
    int main() {
        scanf("%s%s",&a1,&a2);
        int len1 = strlen(a1);
        int len2 = strlen(a2);
        kmp[0] = kmp[1] = 0;
        int k = 0;
        for (int i = 1; i <= len2; i++) {
            while (k && a2[i] != a2[k])
                k = kmp[k];
            kmp[i + 1] = a2[i] == a2[k] ? ++ k : 0;
        }
        k = 0;
        for (int i = 0; i < len1; i++) {
            while (k && a1[i] != a2[k]) 
                k = kmp[k];
            k += a1[i] == a2[k] ? 1 : 0;
            if (k == len2)
                printf("%d
    ",i - len2 + 2); 
        }
        for (int i = 1; i <= len2; i++)
            printf("%d ",kmp[i]);
        return 0;
    }

    P3379 【模板】最近公共祖先(LCA)

    题目描述

    如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。

    输入输出格式

    输入格式:

    第一行包含三个正整数N、M、S,分别表示树的结点个数、询问的个数和树根结点的序号。

    接下来N-1行每行包含两个正整数x、y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树)。

    接下来M行每行包含两个正整数a、b,表示询问a结点和b结点的最近公共祖先。

    输出格式:

    输出包含M行,每行包含一个正整数,依次为每一个询问的结果。

    输入输出样例

    输入样例#1: 
    5 5 4
    3 1
    2 4
    5 1
    1 4
    2 4
    3 2
    3 5
    1 2
    4 5
    输出样例#1: 
    4
    4
    1
    4
    4
    

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=10,M<=10

    对于70%的数据:N<=10000,M<=10000

    对于100%的数据:N<=500000,M<=500000

    样例说明:

    该树结构如下:

    第一次询问:2、4的最近公共祖先,故为4。

    第二次询问:3、2的最近公共祖先,故为4。

    第三次询问:3、5的最近公共祖先,故为1。

    第四次询问:1、2的最近公共祖先,故为4。

    第五次询问:4、5的最近公共祖先,故为4。

    故输出依次为4、4、1、4、4。

    code

    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    const int MAXN = 100010;
    
    int n,m,tot,x,y,a,b,s;
    int father[MAXN][20];
    int dep[MAXN],head[MAXN];
    
    struct edge {
        int next; 
        int node;
        int value;
    }Edge[MAXN];
    
    inline int read() {
        int num = 0 , f = 1;
        char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while (isdigit(ch)) {
            num = num * 10 + ch - '0';
            ch = getchar(); 
        } 
        return num * f;
    }
    
    inline void add(int x,int y) { 
        Edge[++tot].node = x; Edge[tot].next = head[y]; head[y] = tot;
        Edge[++tot].node = y; Edge[tot].next = head[x]; head[x] = tot;
    }
    
    inline void build(int s) {
        for (int i = head[s]; i ; i = Edge[i].next) {
            int v = Edge[i].node;
            if (!dep[v]) {
                dep[v] = dep[s] + 1;    
                father[v][0] = s;
                build(v);
            }
        }
    }
    
    int LCA(int x,int y) {
        if (dep[x] < dep[y])
            swap(x,y);
        for (int i = 19; i >= 0; i--)
            if (dep[father[x][i]] >= dep[y])
                x = father[x][i];
        if (x == y) return y;
        for (int i = 19; i >= 0; i--)
            if (father[x][i] != father[y][i]) {
                x = father[x][i];
                y = father[y][i];
            }
        return father[x][0];
    }
    
    int main() {
        n = read(); m = read(); s = read();
        for(int i = 1; i <= n - 1; i++) {
            x = read(); y = read();
            add(x,y);
        }
        dep[s] = 1; build(s); 
        for (int j = 1; j <= 19; j++)    
            for (int i = 1; i <= n; i++)
                father[i][j] = father[father[i][j - 1]][j - 1];
        for (int i = 1; i <= m; i++){
            a = read(); b = read();
            printf("%d
    ",LCA(a,b));
        }
        return 0;
    }

    P3371 【模板】单源最短路径

    题目描述

    如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

    输入输出格式

    输入格式:

    第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。

    接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。

    输出格式:

    一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)

    输入输出样例

    输入样例#1: 
    4 6 1
    1 2 2
    2 3 2
    2 4 1
    1 3 5
    3 4 3
    1 4 4
    输出样例#1: 
    0 2 4 3

    说明

    时空限制:1000ms,128M

    数据规模:

    对于20%的数据:N<=5,M<=15

    对于40%的数据:N<=100,M<=10000

    对于70%的数据:N<=1000,M<=100000

    对于100%的数据:N<=10000,M<=500000

    样例说明:

    图片1到3和1到4的文字位置调换

    code

    Dijkstra

    #include<cstdio>
    #include<cstring>
    #include<queue>
    
    using namespace std;
    
    const int MAXN = 10010;
    const int MAXM = 500010;
    const int maxx = 2147483647;
    
    int n,m,s,x,y,z,cnt,h,v;
    int head[MAXN],d[MAXN];
    bool vis[MAXN];
    
    queue <int>q;
    
    struct edge{
        int next;
        int node;
        int value;
    }Edge[MAXM];
    
    void add(int u,int v,int w) {
        Edge[++cnt].next = head[u];
        Edge[cnt].node = v;
        Edge[cnt].value = w;
        head[u] = cnt;
    }
    
    void SPFA() {
        while (!q.empty()) q.pop();
        memset(vis,0,sizeof(vis)); 
        q.push(s);
        d[s] = 0; 
        vis[s] = true;
        while (!q.empty()) {
            h = q.front() ;
            q.pop() ;
            vis[h] = 0;
            for (int i = head[h]; i ; i = Edge[i].next) {
                v = Edge[i].node;
                if (d[h] + Edge[i].value < d[v]) {
                    d[v] = d[h] + Edge[i].value;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = true;
                    }
                }
            }
        } 
    }
    
    int main() {
        scanf("%d%d%d",&n,&m,&s);
        for (int i = 1; i <= n; i++)
            d[i] = maxx;
        for (int i = 1; i <= m; i++) {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        SPFA();
        for (int i = 1; i <= n; i++) 
            printf("%d ",d[i]);
        return 0;
    }

    SPFA

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    #define MAXN 500010
    #define oo 2147483647
    
    using namespace std;
    
    int head[MAXN * 2],dis[MAXN],tot,n,m,s;
    bool vis[MAXN];
    
    typedef pair<int, int> pir;
    
    struct Edge {
        int node;
        int next;
        int value;
    }e[MAXN];
    
    inline void add(int x,int y,int z) {
        e[++tot].node = y; e[tot].value = z; e[tot].next = head[x]; head[x] = tot;
    }
    
    priority_queue<pir, vector<pir>, greater<pir> > que;
    
    void dijkstra(int s) {
        dis[s] = 0;
        que.push(make_pair(dis[s], s));
        while (!que.empty()) {
            pir temp = que.top();
            que.pop();
            int x = temp.second;
            if (!vis[x]) {
                vis[x] = true;
                for (int i = head[x]; i ; i = e[i].next) {
                    int v = e[i].node;
                    if (dis[v] > dis[x] + e[i].value) {
                        dis[v] = dis[x] + e[i].value;
                        que.push(make_pair(dis[v],v));
                    }
                }
            }
        }
    }
    
    inline int read() {
        int num = 0, f = 1;
        char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') f = -1;
            ch = getchar(); 
        }
        while (isdigit(ch)) {
            num = num * 10 + ch - '0';
            ch = getchar();
        }
        return num * f;
    }
    
    int main() {
        n = read(); m = read(); s = read();
        for (int i = 1; i <= m; i++) {
            int x,y,z;
            x = read(); y = read(); z = read();
            add(x,y,z);
        }
        for (int i = 1; i <= n; i++) dis[i] = oo;
        dijkstra(s);
        for (int i = 1; i <= n; i++)
            printf("%d ",dis[i]);
        return 0;
    } 

    P3389 【模板】高斯消元法

    题目背景

    Gauss消元

    题目描述

    给定一个线性方程组,对其求解

    输入输出格式

    输入格式:

    第一行,一个正整数 nn

    第二至 n+1n+1 行,每行 n+1n+1 个整数,为 a_1, a_2 cdots a_na1,a2an 和 bb ,代表一组方程。

    输出格式:

    共n行,每行一个数,第 ii 行为 x_ixi (保留2位小数)

    如果不存在唯一解,在第一行输出"No Solution".

    输入输出样例

    输入样例#1: 
    3
    1 3 4 5
    1 4 7 3
    9 3 2 2
    输出样例#1: 
    -0.97
    5.18
    -2.39

    说明

    1 leq n leq 100, left | a_i ight| leq {10}^4 , left |b ight| leq {10}^41n100,ai104,b104

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    
    class Gussian {
        public:
            void init() {
                n = read();
                for (int i = 1; i <= n; ++ i)
                    for (int j = 1; j <= n + 1; ++ j)
                        a[i][j] = read();
            }
            
            void doit() {
                for (int i = 1; i <= n; ++ i) {
                    int k = i; double t;
                    for (int j = i + 1; j <= n; ++ j) 
                           if (Abs(a[k][i]) < Abs(a[j][i])) k = j;
                    if (k != i) for (int j = 1; j <= n + 1; ++ j)
                    t = a[k][j], a[k][j] = a[i][j], a[i][j] = t;
                 if (Abs(a[i][i]) >= eps)
                        for (int j = 1; j <= n; ++ j) { 
                            if (i != j) {
                                t = a[j][i] / a[i][i];
                                for (int k = 1; k <= n + 1; ++ k)
                                    a[j][k] -= t * a[i][k];
                            }
                        }
                }
                int wq = 0, wj = 0;
                for (int i = 1; i <= n; ++ i) {
                    int j = 1;
                    while (Abs(a[i][j]) < eps && j <= n + 1) ++ j;
                    if (j > n + 1) wq = 1;
                    if (j == n + 1) wj = 1; 
                }
                if (wj) { printf("No Solution"); flag = true; return ; }
                if (wq) { printf("No Solution"); flag = true; return ; }
                for (int i = n; i >= 1; -- i) {
                    for (int k = i + 1; k <= n; ++ k)
                        a[i][n+1] -= a[i][k] * f[k];
                    f[i] = a[i][n+1] / a[i][i];
                }
            }
            
            void print() {
                if (!flag) for (int i = 1; i <= n; ++ i) 
                    printf("%.2lf
    ", f[i]);
            }
            
        private:
            const double eps = 1e-5;
            double a[101][101],f[101] = {0};
            int n;
            bool flag = false;
            
            inline int read() {
                int num = 0, f = 1; char ch = getchar();
                while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
                while (isdigit(ch)) { num = num * 10 + ch - '0'; ch = getchar(); } 
                return num * f;
            }
            
            double Abs(double num) { return num < 0 ? - num : num; }
            
    }gussian; 
    
    int main() {
        gussian.init();
        gussian.doit();
        gussian.print();
    }

    中国剩余定理

    LL ex_gcd(LL a,LL b,LL &x,LL &y) {
        if (!b) { x = 1, y = 0; return a; }
        LL d = ex_gcd(b, a % b, x, y);
        LL temp = x; x = y, y = temp - a / b * y;
        return d;
    }
    
    LL china(LL *W, LL *B, LL k) {
        LL x, y, a = 0, m, n = 1;
        for (LL i = 0; i < k; ++ i) n *= W[i];
        for (LL i = 0; i < k; ++ i) {
            m = n / W[i];
            ex_gcd(W[i], m, x, y);
            a = (a + y * m * B[i]) % n;
        }
        return (a + n) % n;
    }

    topsort

    void topsort() {
        queue<int> q;
        for (int i = 1; i <= n; ++ i) if (!indegr[i]) q.push(i);
        while (!q.empty()) {
            int h = q.front();
            q.pop();
            for (int i = head[h], v; i, v = e[i].node ; i = e[i].next) {
                -- indegr[v];
                if (C[h] > 0) C[v] += C[h] * e[i].value;
                if (!indegr[v]) q.push(v);
            }
        }
    }

    不定期更新ing...

  • 相关阅读:
    ArcGIS API中FindTask中文搜索无效,服务器编码问题URIEncoding="utf-8"
    ArcGIS10.1 api for Flex开发用于ArcGIS 9.3时QueryTask 'Error #2032'错误的解决方案
    Arcgis API For IOS扩展AGSDynamicLayer新旧版API对比
    谈FME批量自动化数据转换方法
    浅谈城市规划在移动GIS方面的应用发展
    JS-JQuery(JSONP)调用WebService跨域若干技术点
    CAD规划成果入库GIS_SDE转换之分析
    Web前台直接加载GIS格式数据分析
    [转] 基于ArcGISServer实现活动地图标注
    程序员如何利用空闲时间挣零花钱
  • 原文地址:https://www.cnblogs.com/hkttg/p/9277847.html
Copyright © 2011-2022 走看看