[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 (1≤q≤2⋅1051≤q≤2⋅105) — the number of queries. Then qq queries follow.
The first line of the query contains two integers nn and kk (1≤k≤n≤2⋅1051≤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 2⋅1052⋅105 (∑n≤2⋅105∑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\n",k-ans); 45 46 } 47 48 return 0; 49 }
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 (1≤i<j≤n1≤i<j≤n), then you need to print the kk-th element in the sorted array consisting of all di,jdi,j, where 1≤i<j≤n1≤i<j≤n.
Input
The first line of the input contains three integers n,mn,m and kk (2≤n≤2⋅1052≤n≤2⋅105, n−1≤m≤min(n(n−1)2,2⋅105)n−1≤m≤min(n(n−1)2,2⋅105), 1≤k≤min(n(n−1)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 (1≤x,y≤n1≤x,y≤n, 1≤w≤1091≤w≤109, x≠yx≠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("\ndebug:\n") 14 #define End printf("\nend\n\n") 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\n",kk[k-1]); 73 74 75 return 0; 76 }