zoukankan      html  css  js  c++  java
  • [CF]Codeforces Round #575 (Div. 3)

    D2. RGB Substring (hard version)

    Description

    The only difference between easy and hard versions is the size of the input.

    You are given a string ss consisting of nn characters, each character is 'R', 'G' or 'B'.

    You are also given an integer kk. Your task is to change the minimum number of characters in the initial string ss so that after the changes there will be a string of length kk that is a substring of ss, and is also a substring of the infinite string "RGBRGBRGB ...".

    A string aa is a substring of string bb if there exists a positive integer ii such that a1=bia1=bi, a2=bi+1a2=bi+1, a3=bi+2a3=bi+2, ..., a|a|=bi+|a|1a|a|=bi+|a|−1. For example, strings "GBRG", "B", "BR" are substrings of the infinite string "RGBRGBRGB ..." while "GR", "RGR" and "GGG" are not.

    You have to answer qq independent queries.

    Input

    The first line of the input contains one integer qq (1q21051≤q≤2⋅105) — the number of queries. Then qq queries follow.

    The first line of the query contains two integers nn and kk (1kn21051≤k≤n≤2⋅105) — the length of the string ss and the length of the substring.

    The second line of the query contains a string ss consisting of nn characters 'R', 'G' and 'B'.

    It is guaranteed that the sum of nn over all queries does not exceed 21052⋅105 (n2105∑n≤2⋅105).

    output

    For each query print one integer — the minimum number of characters you need to change in the initial string ss so that after changing there will be a substring of length kk in ss that is also a substring of the infinite string "RGBRGBRGB ...".

    Examples

    Input

    3
    5 2
    BGGGG
    5 3
    RBRGR
    5 5
    BBBRR

    Output

    1
    0
    3

    正确解法:

    给你一个长度为n的字串,让你修改几个字符,使他拥有一个  “RGBRGBR...”长度为k的连续子字符串。

    我们设三个长度为n的字符串:

    RGBRGB...

    GBRGBR...

    BRGBRG...

    分别匹配他与当前字符串的匹配度。

    也就是说如果某个字符相等的话,匹配度+1。

    最后找 长度为k的连续子字符串匹配度的最大值。

    k-这个最大值,就是 修改的最小次数。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <set>
     7 #include <map>
     8 #include <vector>
     9 #include <cctype>
    10 #include <sstream>
    11 using namespace std;
    12 typedef long long ll;
    13 const int inf=0x7fffffff;
    14 const int N=200000+100;
    15 const int M=5000+10;
    16 const double PI=acos(-1.0);
    17 int T;
    18 int n,k;
    19 string s;
    20 string k1="RGB",k2="GBR",k3="BRG";
    21 int sum[5][N];
    22 int main()
    23 {
    24     scanf("%d",&T);
    25     while(T--)
    26     {
    27         scanf("%d %d",&n,&k);
    28         cin>>s;
    29         for(int i=0;i<=n+1;i++)
    30             sum[0][i]=sum[1][i]=sum[2][i]=0;
    31         for(int i=0;i<n;i++)
    32         {
    33             sum[0][i+1]=sum[0][i];
    34             sum[1][i+1]=sum[1][i];
    35             sum[2][i+1]=sum[2][i];
    36             if(s[i]==k1[i%3])   sum[0][i+1]++;
    37             if(s[i]==k2[i%3])   sum[1][i+1]++;
    38             if(s[i]==k3[i%3])   sum[2][i+1]++;
    39         }
    40         int ans=0;
    41         for(int i=0;i+k<=n;i++)
    42             for(int j=0;j<3;j++)
    43                 ans=max(ans,sum[j][i+k]-sum[j][i]);
    44         printf("%d
    ",k-ans);
    45  
    46     }
    47  
    48     return 0;
    49 }
    View Code

    F. K-th Path

    Description

    You are given a connected undirected weighted graph consisting of nn vertices and mm edges.

    You need to print the kk-th smallest shortest path in this graph (paths from the vertex to itself are not counted, paths from ii to jj and from jj to ii are counted as one).

    More formally, if dd is the matrix of shortest paths, where di,jdi,j is the length of the shortest path between vertices ii and jj (1i<jn1≤i<j≤n), then you need to print the kk-th element in the sorted array consisting of all di,jdi,j, where 1i<jn1≤i<j≤n.

    Input

    The first line of the input contains three integers n,mn,m and kk (2n21052≤n≤2⋅105, n1mmin(n(n1)2,2105)n−1≤m≤min(n(n−1)2,2⋅105), 1kmin(n(n1)2,400)1≤k≤min(n(n−1)2,400) — the number of vertices in the graph, the number of edges in the graph and the value of kk, correspondingly.

    Then mm lines follow, each containing three integers xx, yy and ww (1x,yn1≤x,y≤n, 1w1091≤w≤109, xyx≠y) denoting an edge between vertices xx and yy of weight ww.

    It is guaranteed that the given graph is connected (there is a path between any pair of vertices), there are no self-loops (edges connecting the vertex with itself) and multiple edges (for each pair of vertices xx and yy, there is at most one edge between this pair of vertices in the graph).

    output

    Print one integer — the length of the kk-th smallest shortest path in the given graph (paths from the vertex to itself are not counted, paths from ii to jj and from jj to ii are counted as one).

    Examples

    Input

    6 10 5
    2 5 1
    5 3 9
    6 2 2
    1 3 1
    5 1 8
    6 5 10
    1 6 5
    6 4 6
    3 6 2
    3 4 5

    Output

    3

    正确解法:

    问你一个图中,按长度排序第k小的边的长度为多少。

    这肯定不能求最短路,因为不是单点的。

    因为k的范围特别小,我们可以从这里入手。

    我们找k条短边组成一个新图,那么第k小的边一定在这里。

    floyed一下就好了,因为k条边最最多有2*k个点。n^3 的复杂度不会超。

    点那么大怎么组新图呢,离散化啊

    还有一点要注意的是 m不一定大于k。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<string>
     6 #include<map>
     7 #include<set>
     8 #include<vector>
     9 #include<queue>
    10 #include<cmath>
    11 #include<cstdlib>
    12 #include<stack>
    13 #define de printf("
    debug:
    ")
    14 #define End printf("
    end
    
    ")
    15 #define fi first
    16 #define se second
    17 #define P pair< int, int >
    18 #define PII pair< pair<int, int> ,int>
    19 #define INF 0x3f3f3f3f
    20 using namespace std;
    21 typedef long long ll;
    22 const int mod=1e5+7;
    23 const int N=2e5+100;
    24 const int inf=0x7fffffff;
    25 int n,m,k;
    26 ll b[1100][1100];
    27 struct node
    28 {
    29     int x,y,v;
    30 }e[N];
    31 vector<ll>edge,kk;
    32 int cmp(node a,node b)
    33 {
    34     return a.v<b.v;
    35 }
    36 int main()
    37 {
    38     scanf("%d %d %d",&n,&m,&k);
    39     for(int i=1;i<=m;i++)
    40     {
    41         scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);
    42     }
    43     sort(e+1,e+m+1,cmp);
    44     for(int i=1;i<=min(m,k);i++)
    45     {
    46         edge.push_back(e[i].x);
    47         edge.push_back(e[i].y);
    48     }
    49     sort(edge.begin(),edge.end());
    50     edge.resize(unique(edge.begin(),edge.end())-edge.begin());
    51     int cnt=edge.size();
    52     for(int i=0;i<cnt;i++)
    53         for(int j=0;j<cnt;j++)
    54             b[i][j]=1e18;
    55     for(int i=0;i<cnt;i++)
    56         b[i][i]=0;
    57     for(int i=1;i<=min(m,k);i++)
    58     {
    59         int xx=lower_bound(edge.begin(),edge.end(),e[i].x)-edge.begin();
    60         int yy=lower_bound(edge.begin(),edge.end(),e[i].y)-edge.begin();
    61         b[xx][yy]=b[yy][xx]=e[i].v;
    62     }
    63     for(int i=0;i<cnt;i++)
    64         for(int j=0;j<cnt;j++)
    65             for(int k=0;k<cnt;k++)
    66                 if(b[j][k]>b[j][i]+b[i][k])
    67                     b[j][k]=b[j][i]+b[i][k];
    68     for(int i=0;i<cnt;i++)
    69         for(int j=0;j<i;j++)
    70             kk.push_back(b[i][j]);
    71     sort(kk.begin(),kk.end());
    72     printf("%lld
    ",kk[k-1]);
    73 
    74 
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    windows向Linux服务器上传、下载,服务器内复制、移动文件
    解决:ubuntu提示E: 无法获得锁 /var/lib/dpkg/lock-frontend
    PostgreSQL安装与简单操作
    LeetCode 234.回文链表
    LeetCode 445.两数相加 II
    LeetCode 24.两两交换链表中的节点
    LeetCode 19.删除链表的倒数第 n 个节点
    LeetCode 26.删除排序数组中的重复项
    Java 程序运行机制
    String 属于基础的数据类型吗?
  • 原文地址:https://www.cnblogs.com/Kaike/p/11250569.html
Copyright © 2011-2022 走看看