zoukankan      html  css  js  c++  java
  • [HAOI2009] 求回文串

    对于任意输入的字符串,不断将第 (i) 个字符和第 (i+1) 个字符交换,使得该串最终变为回文串。求最少交换次数。(n leq 10^6)

    Solution

    直观的贪心想法:从左向右遍历每个元素,找到序列最右的与它相同的元素,将这两个元素放到目标序列最左、右端然后从原序列中删去,记录下右元素移动的距离就是答案

    然而暴力模拟的复杂度为 (O(n^2)),考虑将每种字符的所有出现位置插入一个 vector 中,同时用一个标记数组来维护每个元素是否已经被删去

    当我们从左侧找元素的时候,如果遇到了一个没有被标记的元素,就意味着我们找到了一个元素

    然后我们通过这个字符的 vector 找到最右侧的相同字符,定位到它的位置,如果这个元素在标记数组中没有被标记,则算找到,否则从 vector 中弹出这个元素并继续找

    找到以后计算贡献,并且将这个右侧元素从 vector 中抹掉,左、右两个元素同时在 vector 中标记

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int ar[N]; // index: 1 ~ N
    int lowbit(int t) { return t & (-t); }
    void add(int i, int v) {
    	for (; i < N; ar[i] += v, i += lowbit(i));
    }
    int sum(int i) {
    	int s = 0;
    	for (; i > 0; s += ar[i], i -= lowbit(i));
    	return s;
    }
    
    char str[N];
    vector <int> v[26];
    
    int n,ans[N],u[N],tot;
    
    signed main() {
        cin>>str+1;
        n=strlen(str+1);
        for(int i=1;i<=n;i++) v[str[i]-'A'].push_back(i);
        int p1=1, p2=n;
        for(int i=1;i<=n;i++) {
            if(u[i]) continue;
            if(p1>=p2) break;
            while(v[str[i]-'A'].size() && u[v[str[i]-'A'].back()])
                v[str[i]-'A'].pop_back();
            if(v[str[i]-'A'].size()==0) {
                cout<<-1;
                return 0;
            }
            int q=v[str[i]-'A'].back();
            if(q==i) continue;
            u[q]=1;
            v[str[i]-'A'].pop_back();
            u[i]=1;
            tot+=abs(p2-q);
            ans[p1++]=i;
            ans[p2--]=q;
        }
        if(p1==p2) {
            int t=0;
            for(int i=1;i<=n;i++) if(u[i]==0) t=i;
            ans[p1]=t;
            tot+=abs(t-p1);
        }
        tot=0;
        for(int i=1;i<=n;i++) {
            tot+=i-1-sum(ans[i]);
            add(ans[i],1);
        }
        cout<<tot;
    }
    
    
  • 相关阅读:
    Array
    ie兼容
    webpack----entry
    webpack——html-webpack-plugin
    webpack 报错 path is not defind
    PHPStorm自动压缩YUI Compressor配置
    fly
    Math.max得到数组中最大值
    简单html弹窗
    js中页面跳转(href)中文参数传输方式
  • 原文地址:https://www.cnblogs.com/mollnn/p/12435061.html
Copyright © 2011-2022 走看看