首页 > 其他分享 >萌熊6月j讲题

萌熊6月j讲题

时间:2024-06-22 22:20:52浏览次数:6  
标签:int 讲题 萌熊 cin bool 序列 解法

A

解法一(官方解法):
要求每段的二进制或都相同,那么如果整个序列中存在某个数的第 \(i\) 位为 \(1\),那么整个序列的每一段长
度为 \(k\) 的连续子序列中都至少有一个数的第 \(i\) 位为 \(1\)。
我们可以对每一位单独求一个满足条件的最小的 \(k\),然后所有位的 \(k\) 的最大值就是答
案。
对于每一位,其序列都形如 00010110001... 这样的二进制串,要求每连续 \(k\) 个位置都至少包含一个 \(1\)。
这是一个很经典的问题,可以用双指针或滑动窗口等方法来实现。
image
image

解法二:
注意到或运算本质上和加法是差不多的,都有单调性,所以可以用线段树+二分求解,其中把线段树中所有的 + 变为 | 即可。

bool mst;
int n,m;
#define ls (p<<1)
#define rs (p<<1|1)
#define int long long
const int N = 5000005;
int a[N];
struct point
{
	int sum,lazy;
}t[N*4];
struct segtree
{
	void push_up(int p)
	{
		t[p].sum = t[ls].sum|t[rs].sum;
	}
	void build(int p,int l,int r)
	{
		if(l==r)
		{
			t[p].sum = a[l];
			return;
		}
		int mid = (l+r)/2;
		build(ls,l,mid);
		build(rs,mid+1,r);
		push_up(p);
	}
	int get(int p,int L,int R,int l,int r)
	{
		if(L<=l&&r<=R)
			return t[p].sum;
		int ans = 0;
		int mid = (l+r)/2;
		if(L<=mid)
			ans |= get(ls,L,R,l,mid);
		if(R>mid)
			ans |= get(rs,L,R,mid+1,r);
		return ans;
	}	
}bird;
bool check(int x)
{
    int c1,c2;
    int i;
    for(i=1;i<=n-x+1;i++)
    {
        c2 = c1;
        c1 = bird.get(1,i,i+x-1,1,n);
        if(~-i&&c1!=c2)
            return 0;
    }
    return 1;
}
bool men;
void solve()
{
    cin>>n;
    int i;
    for(i=1;i<=n;i++)
        cin>>a[i];
    bird.build(1,1,n);
    int l,r;
    l = 1,r = n;
    while(l<r)
    {
        int mid = (l+r)/2;
        if(check(mid))
            r = mid;
        else
            l = mid+1;
    }
    cout<<r<<endl;
    return;
}

B

解法一(官方解法):
image
代码很简单,不给了。
解法二:
可以将上述做法简化,把 dfs 换成递推的过程就可以了。

void solve()
{
    cin>>n>>k;
    int i;
    for(i=1;i<n;i++)
    {
        int u,v;
        cin>>u>>v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    int s = k;
    int j;
    for(i=1;i<=n;i++)
        for(j=2;j<=e[i].size();j++)
            s *= k-j,s %= mod;
    s *= k-1,s %= mod;
    cout<<s%mod<<endl;
    return;
}

C

image

void solve()
{

    queue<int> q[50];
    map<int,bool> ma;
    cin>>n>>m;
    cin>>s+1>>t+1;
    int i,j;
    for(i=1;i<=n;i++)
        ma[s[i]-'a'+1] = 1,q[s[i]-'a'+1].push(i);
    for(i=1;i<=m;i++)
    {
        if(q[t[i]-'a'+1].empty())
        {
            NO
            return;
        }
        int j;
        for(j=1;j<=t[i]-'a'+1;j++)
            while(q[j].size()&&q[j].front()<q[t[i]-'a'+1].front())
                q[j].pop();
        q[t[i]-'a'+1].pop();
    }
    YES
    return;
}

标签:int,讲题,萌熊,cin,bool,序列,解法
From: https://www.cnblogs.com/OoXiaoQioO/p/18262803

相关文章

  • ABC338 A~D讲题
    A\(\text{Link}\)给你一个长度为\(n\)的字符串\(s\),判断\(s\)是否满足以下条件:\(s\)的第一个字符是大写字母,其余字符都是小写字母。代码:#include<bits/stdc++.h>usingnamespacestd;constintMAXN=1e5+5;chars[105];intmain(){ scanf("%s",s+1)......
  • 20230712 讲题
    CF1364DEhab'sLastCorollary简单题。特判掉\(m=n-1\)的情况,此时一定能找到一个大小为\(\left\lceil\frac{k}{2}\right\rceil\)的独立集,二分图染色即可。否则,我们建出dfstree,找到一条连接的两个端点深度之差最小的返祖边,设它为\((u,v)\),且\(dep_u>dep_v\)。......
  • 20230703 讲题
    CF1394DBoboniuandJianghu容易发现若\(b_u\neb_v\)则边的方向确定,问题转化为给\(b_u=b_v\)的边定向。设\(f_{u,0/1}\)为\(u\)连向父亲的点的方向是\(u\tofa\)还是\(fa\tou\)。我们知道一个点的贡献系数是\(\max(in,out)\),其中\(in\)和\(out\)为入......
  • 讲题备用列表
    CF1781G:树,构造,大力分讨:贪心选择,证明合法CF1774G:区间,计数,奇偶抵消,构造树形结构:删除无效区间,其余选下一个,形成树形结构CF1746E2:交互,缩小区间,dp计算最优策略:大约每次......