平时十四测

 

 第一题:蓝书原题,单词建边,跑欧拉路;

无向联通图:欧拉路:有2个度数为奇数的点;

      欧拉回路:没有度数为奇数的点;

有向联通图:欧拉路:每个点入度=出度 或者 起点出度=入度+1 终点出度=入度-1,剩余点出度=入度;

#include<bits/stdc++.h>
using namespace std;
const int ME = 200000 + 5;
int tot = 1, d[ME], h[ME], cur[ME], now, in[ME], out[ME];
//int ru[ME], rv[ME];
bool vis[ME << 1];
struct edge{int v, nxt, id;}G[ME << 1];
int T, N, M;
void add(int u, int v, int id){
    G[++tot].v = v, G[tot].nxt = h[u], G[tot].id = id, h[u] = tot;
}
void print(){
    for(int i = now - 1; i; i--)
        printf("%d ", cur[i]);
    //for(int i = now - 1; i; i--)fprintf(stderr, "%d %d ",
    //ru[cur[i]], rv[cur[i]]);
    puts("");
}
int read(){
    int x = 0; int f = 1; char c = getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
    return x*=f;
}
void dfs(int u, int k){
    for(int i = h[u]; i; i = G[i].nxt){
        if(vis[i])continue;
        int v = G[i].v;
        vis[i] = vis[i^1] = 1;
        dfs(v, i);
    }
    cur[++now] = G[k].id;
}
void dfs2(int u, int k){

    for(int i = h[u]; i; i = G[i].nxt){
        if(vis[i])continue;
        int v = G[i].v;
        //ch++;
        vis[i] = 1;
        dfs2(v, i);
    }
    cur[++now] = G[k].id;    
}

int main(){
    freopen("merge.in","r",stdin);
    freopen("merge.out","w",stdout);
    scanf("%d%d%d", &T, &M, &N);
    if(T == 1){
        for(int i = 1; i <= N; i++){
            int u = read(), v = read();
            add(u, v, i), add(v, u, -i);
            d[u]++, d[v]++;
        }
        int start = 1, cnt = 0;
        for(int i = 1; i <= M; i++)
            if(d[i]&1){start = i;cnt++;}
        if(cnt > 2 || cnt == 1)return !puts("NO");
        
        dfs(start, 0);
        if(now != N+1)return !puts("NO");
        puts("YES");
        print();
        
    }
    else {
        for(int i = 1; i <= N; i++){
            int u = read(), v = read();
            add(u, v, i);out[u]++, in[v]++;
            //ru[i]=u,rv[i]=v;
        }
        int st = -1, ed = -1, cnt = 0;
        for(int i = 1; i <= M; i++)
            if(in[i] != out[i]){
                if(in[i]+1 == out[i])st = i;
                if(in[i]-1 == out[i])ed = i;
                cnt++;
            }
        if((cnt != 0 && cnt != 2) || ((st == -1 || ed == -1) && cnt != 0))return !puts("NO");
        if(st == -1)for(int i = 1; i <= N; i++)
            if(in[i]) {st = i;break;}
        dfs2(st, 0);
        if(now != N+1)return !puts("NO");
        puts("YES");
        print();
        return 0;
    }
}
View Code

第二题:有一个性质,发现就好做了,但我根本没有去思考,思维僵化啊;

#include<bits/stdc++.h>
using namespace std;
const  int M = 200005, inf = 1e9;
int a[M], n,t[M], c[M];
long long Ans;
bool vis[M];
void add(int x){
    for(; x <= n; x += x&(-x))
        c[x] ++;
}
int query(int x){
    int ret = 0;
    if(!x)return 0;
    for(; x; x -= x&(-x))
        ret += c[x];
    return ret;
}
#define Ls nd->ls, lf, mid
#define Rs nd->rs, mid+1, rg
struct Node{
    int v;
    Node *ls, *rs;
    void up(){
        v = min(ls->v, rs->v);
    }
}pool[M << 2], *root, *tail = pool; 
Node *build(int lf = 1, int rg = n){
    Node *nd = ++tail;
    if(lf == rg)nd->v = a[lf];
    else {
        int mid = (lf + rg) >> 1;
        nd->ls = build(lf, mid);
        nd->rs = build(mid+1, rg);
        nd->up();
    }
    return nd;
}
void modify(int pos, Node *nd = root, int lf = 1, int rg = n){
    if(lf == rg){
        if(nd->v <= a[pos]){
            Ans -= t[lf];
            nd->v = inf;    
        } 
    }
    else {
        int mid = (lf + rg) >> 1;
        if(pos <= mid && nd->ls->v <= a[pos])modify(pos, Ls);
        if(nd->rs->v <= a[pos])modify(pos, Rs);
        nd->up();
    }
}
int read(){
    int x = 0; int f = 1; char c = getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
    return x*=f;
}
int main(){
    freopen("count.in","r",stdin);
    freopen("count.out","w",stdout);
    int m, k;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)a[i] = read();
    for(int i = n; i; i--){
        t[i] = query(a[i]-1);
        add(a[i]);
    }
    for(int i = 1; i <= n; i++)Ans += 1LL*t[i];
    printf("%lld ", Ans);
    root = build();
    for(int i = 1; i <= m; i++){
        k = read();
        modify(k);
        if(i != m)printf("%lld ", Ans);
        else printf("%lld
", Ans);
    }
}
View Code
原文地址:https://www.cnblogs.com/EdSheeran/p/9845610.html