zoukankan      html  css  js  c++  java
  • P6140 [USACO07NOV]Best Cow Line S

    很容易想到对于原串的两端,选择字典序最小的,如果相同,则往里面找,找到不相同的再比较大小,取最小的。可以用字符串hash优化到(O(n log n))

    
    const int N = 5e5 + 79;
    int n, len;
    char s[N];
    char ans[N];
    const ull base = 1e9 + 7;
    ull h[N], hash1[N],hash2[N];
    
    int L, R;
    
    inline ull H1(int l, int r) {
    	return hash1[r] - hash1[l - 1] * h[r - l + 1];
    }
    
    inline ull H2(int r, int l) {
    	return hash2[r] - hash2[l + 1] * h[l - r + 1];
    }
    
    inline bool check(int len) {
    	return H1(L, L + len - 1) == H2(R - len + 1, R);
    }
    
    
    
    inline char gt() {
    	static char buf[1 << 21], *p1 = buf, *p2 = buf;
    	return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
    }
    template <typename T>
    inline void  read(T &x) {
    	char ch = gt();
    	x = 0;
    	int w(0);
    	while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt();
    	while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt();
    	w ? x = ~(x - 1) : x;
    }
    
    inline int find() {
    	int l(1), r( (R - L + 1) >> 1 ), mid, ans(1);
    	while(l <= r) {
    		mid = (l + r) >> 1;
    		if(check(mid)) {
    			l = mid + 1;
    			ans = mid;
    		} else {
    			r = mid - 1;
    		}
    	}
    	return ans;
    }
    
    
    
    int main() {
    read(n);
    	s[0] = '0';
    	rep(i, 1, n) {
    		while((s[i]=gt())<'A'||s[i]>'Z');
    	}
    	h[0] = 1;
    	rep(i, 1, n) {
    		h[i] = h[i - 1] * base;
    		hash1[i] = hash1[i - 1] * base + s[i];
    	}
    	drp(i, n, 1) {
    		hash2[i] = hash2[i + 1] * base + s[i];
    	}
    
    	L = 1, R = n;
    	ans[0] = '0';
    	while(L < R) {
    		if(s[L] < s[R]) {
    			ans[++len] = s[L++];
    		} else if(s[L] > s[R]) {
    			ans[++len] = s[R--];
    		} else {
    			int Len = find(); //ÏàµÈµÄ³¤¶È
    			ans[++len] = s[L + Len] < s[R - Len] ? s[L++] : s[R--];
    		}
    	}
    	ans[++len] = s[L];
    	rep(i, 1, len) {
    		putchar(ans[i]);
    		if(!(i % 80)) putchar('
    ');
    	}
    	return 0;
    }
    

    本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15463469.html

  • 相关阅读:
    万里长征,始于足下——菜鸟程序员的学习总结(二)
    google云笔记keep试用感受
    程序员英语学习—理论篇(一)
    LLVM每日谈之十六 LLVM的学习感悟
    LLVM每日谈之十五 LLVM自带的examples
    C++学习书单
    人品计算器小案例
    隐式意图&显示意图
    Activity有多个启动图标
    Android中四大组件
  • 原文地址:https://www.cnblogs.com/QQ2519/p/15463469.html
Copyright © 2011-2022 走看看