• [树状数组][哈希]JZOJ 3240 Seat


    Description

    你和你的伙伴正在筹备村里的万人宴,由于村子是长条形的,所有宾客将坐在一张超级长桌的一侧就餐。

    正当筹备工作进行得火热朝天,你和你的伙伴发现一个严重问题:由于缺乏沟通,你俩各自制作了一张座位图发给各位宾客。你必须计算出有多少对宾客,他们在两份座位图中次序安排是不同的。

    例如,对以下两份座位图:

    A B C D E

    B A D E C

    有三对宾客(A,B),(C,D)和(C,E),他们在两份座位图中的次序不同。
     

    Input

    输入的第一行是一个整数N(1<=N<=100000),代表宾客的数量。接下来的两行分别代表两张座位图。每行由N个空格分隔的字符串组成,这些字符串代表宾客,宾客名互不相同,只包含字母,长度不超过5个字符。两张座位图上的宾客名单保证是一致的。

    Output

    输出一个整数,代表有多少对宾客被两份座位图安排了不同的次序。
     

    Sample Input

    输入1:
    3
    Frank Sam Billy
    Sam Frank Billy

    输入2:
    5
    A B C D E
    B A D E C
     

    Sample Output

    输出1:
    1

    输出2:
    3
     

    Data Constraint

    1<=N<=100000

    分析

    题意简单:给定一个标准,让你求另一个序列的逆序对数

    序列都是字符串形式,字符串哈希即可,这里我选择map(反正也能过)

    然后用树状数组经典求法即可

    #include <iostream>
    #include <cstdio>
    #include <map>
    #include <cstring>
    #include <string>
    #define lowbit(x) x&-x
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    ll t[N],ans;
    int a[N];
    map<string,int> h;
    string c;
    int n,cnt;
    
    void Add(int x) {
        for (;x<N;x+=lowbit(x)) t[x]++;
    }
    
    ll Sum(int x) {
        ll ans=0;
        for (;x;x-=lowbit(x)) ans+=t[x];
        return ans;
    }
    
    int main() {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) {    
            cin>>c;
            h[c]=++cnt;
        }
        for (int i=1;i<=n;i++) {
            cin>>c;
            a[i]=h[c];
        }
        for (int i=n;i;i--)
         ans+=Sum(a[i]),Add(a[i]);
        printf("%lld",ans);
        return 0;
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    trie树
    基数排序
    CF724E Goods transportation 最小割 DP
    [CQOI2009]跳舞 网络流
    NOIP2018爆零记
    斜率优化
    CF311B Cats Transport 斜率优化DP
    逆元
    卡特兰数
    【BZOJ】【1565】【NOI2009】PVZ 植物大战僵尸
  • 原文地址:https://www.cnblogs.com/mastervan/p/11117918.html
Copyright © 2020-2023  润新知