给定一个由0和/或1组成的大小为n的字符串。您必须执行 k 查询,并且可能有两种类型的查询。
输入格式:
输出格式:对于类型1的每个查询,在新行中打印子阵列的最大大小 全是1。
Example Input: Example Output: 5 7 0 00000 1 1 1 2 3 3 1 2 5 1 2 4 1
我的解决方案:O(k * n)(如果大多数类型1的查询)
if(type==1){
int count=0, ans=0;
for(int i=0;i<str.size();i++){ //longest len substring
if(str[i]=='1'){
count++;
}else{
ans=max(ans,count);
count=0;
}
}
printf("%d\n",ans);
}else{
int xth;
scanf("%d",&xth);
str[xth-1]='1'; //update
}
我无法找到一个有效的解决方案,因为'type 1'查询只有我能想到的解决方案是每次迭代字符串并连续保持一个“count”变量并最终更新“ans” “当ith str成为'0'时变量。
我正在考虑使用分段树但不知道该怎么做。根据需要,良好的解决方案应该是O(k * log(n))(在log(n)时间内执行“type1”查询)
答案 0 :(得分:1)
这可以使用Disjoint sets datastructure解决,其中每个数字都是空集。
当&#34; 0&#34;将索引i
翻转为&#34; 0&#34;。检查是否item[i-1] == 1
,如果是,请将集{i}
加入包含i-1
的集合。与item[i+1]
类似。
由于你永远不会断开&#34; sets&#34;,你可以缓存&#34;最长的子串&#34;当你计算新的集合时(通过检查你刚创建的新子集现在是否最长,如果是,则存储相关长度)
对于&#34; 1&#34;此解决方案的时间复杂度为O(1)
。键入操作,O(alpha(n))
用于&#34; 2&#34;类型操作(其中alpha:N->N
是反ackerman,这是sublogarithmic)。
这可以为O(k*alpha(n))
个查询提供k
最差案例效果。
所以,举个例子:
5 7
Create 5 sets: {1} {2} {3} {4} {5}
00000
1
Nothing cached, answer is 0
2 3
2 and 4 are zeros, so don't connect with anything. Cache biggest length 1 ({3})
1
1 is cached
2 5
Flip 5. Don't connect with anything.
1
1 is cached
2 4
Flip 4. Join({3},{4}) Since both are 1. Join({3,4},{5}) similarly. Cache 3 (since it's the new size of the set contianing 4 is bigger than 1).
1
3 is cached.
答案 1 :(得分:0)
绝对完美@amit基于他的解释,这里是c ++实现
这里的等级是维持最大构成1,因此您可以在O(1)时间内返回查询1,因为SOl在更新时始终具有最大值1
#include <bits/stdc++.h>
using namespace std;
typedef struct subset
{
int parent;
int rank;
}subset;
int find(subset subsets[], int i)
{
if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}
void Union(subset subsets[], int x, int y)
{
int xroot = find(subsets, x);
int yroot = find(subsets, y);
if(subsets[xroot].rank < subsets[yroot].rank)
{
subsets[xroot].parent = yroot;
subsets[yroot].rank += subsets[xroot].rank;
}
else if (subsets[xroot].rank > subsets[yroot].rank)
{
subsets[yroot].parent = xroot;
subsets[xroot].rank += subsets[yroot].rank;
}
else
{
subsets[yroot].parent = xroot;
subsets[xroot].rank+=subsets[yroot].rank;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,k,i,q,t,sol=0;
cin >> n >> k;
string s;
cin >> s;
cin.ignore();
subset subsets[n];
for(i=0;i<n;i++)
{
subsets[i].parent = i;
subsets[i].rank = 0;
if(s[i]=='1')
{
subsets[i].rank = 1;
}
}
for(t=0;t<n;t++)
{
if(s[t] == '1' && t!=0 && t!=n-1)
{
if(s[t-1] == '1')
{
int x = find(subsets,t-1);
int y = find(subsets,t);
if(x!=y)
{
Union(subsets,t-1,t);
sol = max(sol,max(subsets[x].rank,subsets[y].rank));
sol = max(sol,subsets[t].rank);
}
}
if(s[t+1] == '1')
{
int x = find(subsets,t+1);
int y = find(subsets,t);
if(x!=y)
{
Union(subsets,t+1,t);
sol = max(sol,max(subsets[x].rank,subsets[y].rank));
sol = max(sol,subsets[t].rank);
}
}
}
if(s[t] == '1' && t==0 )
{
if(s[t+1] == '1')
{
int x = find(subsets,t+1);
int y = find(subsets,t);
if(x!=y)
{
Union(subsets,t+1,t);
sol = max(sol,max(subsets[x].rank,subsets[y].rank));
sol = max(sol,subsets[t].rank);
}
}
}
if(s[t] == '1' && t==n-1)
{
if(s[t-1] == '1')
{
int x = find(subsets,t-1);
int y = find(subsets,t);
if(x!=y)
{
Union(subsets,t-1,t);
sol = max(sol,max(subsets[x].rank,subsets[y].rank));
sol = max(sol,subsets[t].rank);
}
}
}
sol = max(sol,subsets[t].rank);
}
for(i=0;i<k;i++)
{
cin >> q;
if(q==1)
{
cout << sol << endl;
}
else
{
cin >> t;
t--;
if(s[t] == '0' && t!=0 && t!=n-1)
{
s[t] = '1';
subsets[t].rank = 1;
if(s[t-1] == '1')
{
int x = find(subsets,t-1);
int y = find(subsets,t);
if(x!=y)
{
Union(subsets,t-1,t);
sol = max(sol,max(subsets[x].rank,subsets[y].rank));
sol = max(sol,subsets[t].rank);
}
}
if(s[t+1] == '1')
{
int x = find(subsets,t+1);
int y = find(subsets,t);
if(x!=y)
{
Union(subsets,t+1,t);
sol = max(sol,max(subsets[x].rank,subsets[y].rank));
sol = max(sol,subsets[t].rank);
}
//Union(subsets,t+1,t);
}
}
if(s[t] == '0' && t==0 )
{
s[t] = '1';
subsets[t].rank = 1;
if(s[t+1] == '1')
{
int x = find(subsets,t+1);
int y = find(subsets,t);
if(x!=y)
{
Union(subsets,t+1,t);
sol = max(sol,max(subsets[x].rank,subsets[y].rank));
sol = max(sol,subsets[t].rank);
}
}
}
if(s[t] == '0' && t==n-1)
{
s[t] = '1';
subsets[t].rank = 1;
if(s[t-1] == '1')
{
int x = find(subsets,t-1);
int y = find(subsets,t);
if(x!=y)
{
Union(subsets,t-1,t);
sol = max(sol,max(subsets[x].rank,subsets[y].rank));
sol = max(sol,subsets[t].rank);
}
}
}
sol = max(sol,subsets[t].rank);
}
}
}