zoukankan      html  css  js  c++  java
  • codeforces 1256F Equalizing Two Strings 题解

    Codeforces Round #598 (Div. 3) F

    首先无论反转多长的子串 最后的效果能够等同于进行若干次相邻两个字母交换
    把相邻交换看作后者前移

    abcd->abdc->adbc->dabc
    dabc->dacb->dcab
    dcab->dcab
    dcba
    

    接下来分类讨论

    • 如果有字母在S和T中出现次数不同

    显然 (sf{NO}) 这还需要解释吗

    • 如果S和T中存在一个字母出现不止一次

    把 S 中这两个字母想办法变成相邻 这一定能做到
    然后每次操作交换 S 的这两个相邻字母 T就可以任意交换
    S 不变 T 一定可以变成 S

    因为可以看作每一个字符任意右移 每次把需要移动的移过去就行了

    • 其它情况

    我们可以先想办法把 S 变成升序 同时对T任意选择两个相邻字母每次交换这两个 这一步的次数取决于 S 中逆序对的个数 假设这个数为(x)
    这样之后再把 T 变成升序 假设 T 中逆序对个数为(y) 这一步需要的步数等于(y+1)(y-1)((x)为奇数) 或 (y)((x)为偶数)

    如果(x)为奇数 在"任意选择两个相邻字母每次交换这两个"操作中 S排序完后T的逆序对显然会增加或减少一个 而如果(x)为偶数 这个数不会改变

    同时也要在S上进行这些操作(任意选择两个相邻字母每次交换这两个)

    可以看出(x+y)为偶数是能做到上面一步 否则如果一个为升序 另一个逆序对必会为1

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    
    LL T,n;
    string s,t;
    LL cnt[2][28] = {0};
    
    LL tr[35] = {0};
    LL lowbit(LL x){ return (x & (-x)); }
    void modify(LL x){ for(;x <= 26;x += lowbit(x)) tr[x] ++; }
    LL query(LL x){ LL ret = 0; for(;x;x -= lowbit(x)) ret += tr[x]; return ret; }
    // 树状数组求逆序对
    // 好像没必要啊
    
    int main(){
    	cin >> T;
    	while(T --){
    		memset(cnt,0,sizeof(cnt));
    		cin >> n; cin >> s >> t;
    		for(LL i = 0;i < n;i ++){
    			cnt[0][s[i] - 'a' + 1] ++;
    			cnt[1][t[i] - 'a' + 1] ++;
    		}
    		
    		LL dif = 0; for(LL i = 1;i <= 26;i ++) if(cnt[0][i] != cnt[1][i]) dif = 1;
    		if(dif){ cout << "NO" << endl; continue; }
    		    // 情况1
          LL sam = 0; for(LL i = 1;i <= 26;i ++) if(cnt[0][i] >= 2) sam = 1;
    		if(sam){ cout << "YES" << endl; continue; }
            // 情况2
    		
    		LL ans = 0,ant = 0;
    		memset(tr,0,sizeof(tr));
    		for(LL i = 0;i < n;i ++){ ans += query(s[i] - 'a' + 1); modify(s[i] - 'a' + 1); }
    		memset(tr,0,sizeof(tr));
    		for(LL i = 0;i < n;i ++){ ant += query(t[i] - 'a' + 1); modify(t[i] - 'a' + 1); }
    		
    		cout << ((ans & 1) == (ant & 1) ? "YES" : "NO") << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    VOA 2009/11/02 DEVELOPMENT REPORT In Kenya, a Better Life Through Mobile Money
    2009.11.26教育报道在美留学生数量创历史新高
    Java中如何实现Tree的数据结构算法
    The Python Tutorial
    VOA HEALTH REPORT Debate Over New Guidelines for Breast Cancer Screening
    VOA ECONOMICS REPORT Nearly Half of US Jobs Now Held by Women
    VOA ECONOMICS REPORT Junior Achievement Marks 90 Years of Business Education
    VOA 2009/11/07 IN THE NEWS A Second Term for Karzai; US Jobless Rate at 10.2%
    Ant入门
    Python 与系统管理
  • 原文地址:https://www.cnblogs.com/IltzInstallBI/p/12744225.html
Copyright © 2011-2022 走看看