zoukankan      html  css  js  c++  java
  • codeforces 217E 【Alien DNA】

    倒序考虑每一个操作,对于一个操作$[l, r]$,他产生的影响区间将是$[r+1,r + r + l - 1]$,如果$r+l-1>K$的话,$K$之后的区间我们是不关心的。

    暴力扫描这个区间 然后对于每一个位置,维护一个类似于并查集的东西。

    扫到位置$i$,定义数组$f$ 表示$i$这个位置上的字符是由$f_i$这个位置上的字符填充得到的。然后删除$i$。

    这个东西具体怎么搞?我们可以弄一个长度为K,初始化为1的序列。获得第$i$个位置就是这个序列上第$i$个1,然后删除这个位置上的字符,就是把序列上该位置的1变成0。维护这个序列的话树状数组+二分或者树状数组+倍增花式搞,我选择后者,毕竟前者复杂度多一个$log$。不会的话可以看lyd那本书的P203(第一版),或者做一下poj 2182.

    当然线段树维护也是可以的啦~

    所以我们就得到如下算法:

    倒序扫描每一个操作,维护一个变量$now$表示我们关心的区间末尾,对于每次操作的区间$[l,r]$,用一个变量$x$扫描$[r+1,r+l-1]$所要填充的字符的位置。每填充一个数$now$就减一,如果$r>now$就直接停止。因为$now$的缘故,最多填充次数为$K$。每次填充时,设$tmp$为01序列中第$r+1$个1,那么将$tmp$位置上的数减一,然后更新$f_{tmp}$为第$x$个1的位置

    然后从左往右求解,如果$f_i$存在,那么$ans_i=ans_{f_i}$,不然$ans_i=s_{j+1},j++$ 由于$f_i$必然比$i$小 所以这样做一定是正确的

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int N = 3e6 + 10;
    char s[N], ans[N];
    int n, K, len, f[N], c[N];
    struct OPT{ int l, r;}a[5050];
    int lowbit(int x){ return x & -x;}
    void add(int x, int val){
    	for(int i = x; i <= K; i += lowbit(i))	  c[i] += val;
    }
    int get(int x){
    	int l = log2(K), sum = 0, ans = 0;
    	for(int i = l; i >= 0; i--){
    		int k = (1 << i);
    		if(ans + k <= K && sum + c[ans + k] < x)
    		  sum += c[ans + k], ans += k;
    	}
    	return ans + 1;
    }
    int main(){
    	scanf("%s", s + 1);
    	scanf("%d%d", &K, &n);
    	for(int i = 1; i <= K; i++) c[i] = i & -i; //初始化树状数组为1
    	for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].l, &a[i].r);
    	for(int now = K, i = n; i; i--)
    	  for(int x = a[i].l + 1, j = 1; a[i].r < now && j <= a[i].r - a[i].l + 1; x += 2, j++, now--){
    		  if(x > a[i].r) x = a[i].l;
    		  int tmp = get(a[i].r + 1); add(tmp, -1), f[tmp] = get(x);
    	  }
    	for(int i = 1, j = 0; i <= K; i++)
    	  ans[i] = f[i] ? ans[f[i]] : s[++j];
    	puts(ans + 1);
    	return 0;
    }
    

      

  • 相关阅读:
    C# Debugger.IsAttached 调试启动浏览器 VS if DEBUG 启动调试内容
    【转载】如何三个月从零基础到C#中级程序员
    【转载】如何成为一个高级程序员
    如何找回QQ聊天记录、语音、图片?
    hexo博客yili主题个性化自定义教程(1) ——借鉴中学习,初认yili主题
    2019hexo博客部署到coding该绕的坑-奥怪的小栈
    2019Hexo博客Next主题深度美化 打造一个炫酷博客(2)-奥怪的小栈
    2019软件工程专业大学排名附官网-奥怪的小栈
    浅谈互联网+足球
    2019基于Hexo快速搭建个人博客,打造一个炫酷博客(1)-奥怪的小栈
  • 原文地址:https://www.cnblogs.com/Rorshach/p/9846884.html
Copyright © 2011-2022 走看看