zoukankan      html  css  js  c++  java
  • bzoj2217 [Poi2011]Lollipop

    [Poi2011]Lollipop

    Time Limit: 15 Sec Memory Limit: 64 MBSec Special Judge

    Description

    有一个长度为n的序列a1,a2,...,an。其中ai要么是1("W"),要么是2("T")。
    现在有m个询问,每个询问是询问有没有一个连续的子序列,满足其和为q。

    Input

    第一行n,m (1<=n,m<=1000000)
    第二行这个序列,起始编号为1,终止编号为n
    下面每行一个询问q,询问有没有一个连续的子序列,满足其和为q (1<=q<=2000000)

    Output

    对于每个询问,输出一行,如果有,输出这个序列的起点和终点(如果有多个输出任意一个);如果没有,输出“NIE”。

    Sample Input

    5 3

    TWTWT

    5

    1

    7

    Sample Output

    1 3

    2 2

    NIE


    大概就是有一些想法,比如如果一个奇数能被凑出来,那么比这个奇数小的奇数也一定能够凑出来。。。。偶数同理。 然后呢还有一个就是任何一个区间都可以从【1,x】这个区间整体平移几位凑出来。再进一步说,如果说你要凑t,那么要么有一个【1,x】直接满足,要么有一个【1,x】为t+1 然后呢你就开始平移,直到左边减去的一个和右边加的一个一个1一个2就凑出来了。
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6 + 6;
    struct ld{
    	int data, tw;
    }num[maxn];
    char s[maxn];
    int n, m, x, lpd, sum1, sum2, f[maxn * 2], lll[maxn * 2], rrr[maxn * 2];
    
    inline void putit()
    {
    	scanf("%d%d", &n, &m); scanf("%s", s + 1);
    	for(int i = 1; i <= n; ++i){
    		if(s[i] == 'W') num[i].data = 1;
    		if(s[i] == 'T') num[i].data = 2;
    	}
    	for(int i = n; i >= 1; --i){
    		num[i].tw = num[i + 1].tw + 1;
    		if(s[i] == 'W')	num[i].tw = 0;
    	}	
    }
    
    void workk()
    {
    	int sum = 0;
    	for(int i = 1; i <= n; ++i){
    		sum += num[i].data;
    		if(s[i]=='T')
            {
                if(num[1].tw < num[i].tw)
                    lll[sum - 1] = num[1].tw + 2, rrr[sum - 1] = i + num[1].tw;
                else if(i + num[i].tw != n + 1)
                    lll[sum - 1] = 1 + num[i].tw, rrr[sum - 1] = i + num[i].tw;
            }
    	}
    }
    
    inline void prepare()
    {
    	int lin = 0; 
    	for(int i = 1; i <= n; ++i){
    		lin += num[i].data;
    		f[lin] = i; 
    		lll[lin] = 1; rrr[lin] = i;		
    	} 
    
    	sum1 = lin;
    	int lin1 = sum1, lin2 = sum1;
    	for(int i = 1; i <= n; ++i){
    		lin1 -= num[i].data;
    		if(num[i].data == 1) break;
    	}
    	for(int i = n; i >= 1; --i){
    		lin2 -= num[i].data;
    		if(num[i].data == 1) break;
    	}
    	sum2 = max(lin1, lin2);
    }
    
    int main()
    {
    	//freopen("data.in", "r", stdin);
    	//freopen("lpl.out", "w", stdout);
    	putit();
    	prepare();
    	workk();
    	for(int i = 1; i <= m; ++i){
    		scanf("%d", &x);
    		if(lll[x] == 0) puts("NIE");
    		else printf("%d %d
    ", lll[x], rrr[x]);
    	}
    	return 0;
    }
    
    
    心如花木,向阳而生。
  • 相关阅读:
    Spread for Windows Forms快速入门(2)设置Spread表单
    Spread for Windows Forms快速入门(3)行列操作
    Html5 Canvas 扫雷 (IE9测试通过)
    Web页面中5种超酷的Hover效果
    文字处理控件功能比较:TX Text Control vs. RichTextBox
    Spread for Windows Forms快速入门(7)单元格的交互操作
    Spread for Windows Forms快速入门(6)定义单元格的外观
    Html5 Rocks 镜像
    如何在ASP.NET中生成HTML5离线Web应用
    Spread for Windows Forms快速入门(5)常用的单元格类型(下)
  • 原文地址:https://www.cnblogs.com/LLppdd/p/9175966.html
Copyright © 2011-2022 走看看