首页 > 其他分享 >2023牛客暑期多校训练营9

2023牛客暑期多校训练营9

时间:2023-09-05 21:44:37浏览次数:32  
标签:5005 int ans 多校 back 牛客 2023 区间 id

D.Non-Puzzle: Error Permutation

题意:给出一个排列,计算其有多少个子区间,满足区间内的第\(i\)个数不是第\(i\)小的数

Solution

首先明白一点,对于一个数,它的大小排序只会变大而不会变小,变大的要求是后面遇到比它小的数。

所以我们可以发现,对于一个数,它会有以下几种情况:

1.在开始的一段区间内不是第\(i\)小的数,在中间的一段区间内是第\(i\)小的数,在后面的区间内不是第\(i\)小的数

2.在开始的一段区间内是第\(i\)小的数,在后面的区间内不是第\(i\)小的数

于是我们可以通过枚举左端点,然后遍历从左端点开始的每一个数,处理出哪些点是不合法的,剩下的就是合法的答案了。

真ex,被卡常了,还以为思路错了

int a[5005];
int e[5005][5005];
int g[5005];
int cnt[5005][5005];
int vis[5005];
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        g[i]=0;
        vis[i] = 0;
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j < i; j++)
        {
            if (a[i] < a[j])e[j][g[j]++]=i;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= i; j++)
        {
            cnt[i][j] = cnt[i][j - 1];
            if (a[j] < a[i])
                cnt[i][j] += 1;
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        for (int j = i; j <= n; j++)
        {
            int pos = cnt[j][j] - cnt[j][i - 1] + 1, num = j - i + 1;
            // cout<<a[j]<<":"<<pos<<"\n";
            int l = num - pos;
            if (l == 0)
                vis[j]--;

            if (g[j] < l)
                continue;

            if (l == 0)
            {
                if (g[j] == 0)
                    continue;
                int posr = e[j][0];
                vis[posr]++;
            }
            else if (g[j] == l)
            {
                int posl = e[j][l - 1];
                vis[posl]--;
            }
            else
            {
                int posl = e[j][l - 1], posr = e[j][l];
                vis[posl]--;
                vis[posr]++;
            }
           /* for (int k = i; k <= n; k++)
            {
                cout << vis[k] << " \n"[k == n];
            }*/
        }

        for (int j = i; j <= n; j++)
        {
            vis[j] += vis[j - 1];
            if (vis[j] >= 0)
                ans++;
        }
        for (int j = 1; j <= n; j++)
            vis[j] = 0;
       // cout << ans << "\n";
    }
    cout << ans << "\n";
}

E.Puzzle: Square Jam

题意:给出一个\(n\times m\)的矩形,要求把它分成若干个正方形,使得每个点(包括正方形上的不被四个正方形所包含)QQ截图20230905113421

Solution

贪心,看长和宽,哪个短一些就取了作为正方形边长,然后递归即可

struct node
{
	int sx,sy,a;
};

vector<node>ans;
void dfs(int sx,int sy,int x,int y)
{
	//cout<<sx<<" "<<sy<<" "<<x<<" "<<y<<"\n";
	if(x==1&&y==1)
	{
		ans.push_back({sx,sy,1});
		return;
	}
	if(x==y)
	{
		ans.push_back({sx,sy,x});
	}
	else if(x>y)
	{
		for(int i=1;i<=x/y;i++)
		{
			ans.push_back({sx+(i-1)*y,sy,y});
		}
		if(x%y)dfs(sx+(x/y)*y,sy,x%y,y);
	}else
	{
		for(int i=1;i<=y/x;i++)
		{
			ans.push_back({sx,sy+(i-1)*x,x});
		}
		if(y%x)dfs(sx,sy+(y/x)*x,x,y%x);
	}
}


void solve()
{
	ans.clear();
	int x,y;cin>>x>>y;
	dfs(0,0,x,y);
	cout<<"YES\n";
	cout<<ans.size()<<"\n";
	for(auto it:ans)
	{
		cout<<it.sx<<" "<<it.sy<<" "<<it.a<<"\n";
	}
}

I.Non-Puzzle: Segment Pair

题意:给出\(n\)对区间,每对可以选择其中的一个,问有多少种选法,可以使得选出的\(n\)个区间至少有一个点重合。

Solution

把所有区间用差分操作的形式表示,考虑枚举每一段区间,定义数组\(b[0/1/2]\)表示当前这段区间被某一组区间所覆盖的个数为\(0/1/2\)个,那么当且仅当\(b[0]\)为\(0\)的时候才对答案有贡献,贡献为\(2^{b[2]}\)

懵哥真厉害,完全想不到的维护操作

int b[3];

struct node
{
    int x, y, id;
    bool operator<(const node &t) const &
    {
        if (x != t.x)
            return x < t.x;
        return y < t.y;
    }
};
int a[N];//表示第i组区间对当前区间的覆盖数
void solve()
{
    int n;
    cin >> n;
    int maxx = 0;
    vector<node> v;
    for (int i = 1; i <= n; i++)
    {
        int l1, r1, l2, r2;
        cin >> l1 >> r1 >> l2 >> r2;
        v.push_back({l1, 1, i});
        v.push_back({r1 + 1, -1, i});
        v.push_back({l2, 1, i});
        v.push_back({r2 + 1, -1, i});
    }
    sort(v.begin(), v.end());

    int ans = 0;
    b[0] = n;
    for (auto it : v)
    {
        b[a[it.id]]--;
        a[it.id] += it.y;
        if (it.y == 1 && !b[0])
        {
            ans = (ans + ksm(2, b[2])) % mod;
        }
        b[a[it.id]]++;
    }

    cout << ans << "\n";
}

标签:5005,int,ans,多校,back,牛客,2023,区间,id
From: https://www.cnblogs.com/HikariFears/p/17680913.html

相关文章

  • 百望云入选2023数字新消费“财税法数字化最佳服务商榜”
    当下,数字经济正在以前所未有的速度和影响力,不断推动生产方式和生活方式发生深刻变革,企业常常要面对从未遇到的新挑战。新的技术革新赋能企业创新生产力,越来越多的企业已经开展了数字化实践,数字化转型成为企业发展的关键。近日,第一新声联合天眼查正式发布2023中国数字新消费系列榜单......
  • 2023你需要使用的最佳VSCode扩展
    VisualStudioCode(VSCode)是一款广受欢迎的多功能代码编辑器,在最新的StackOverflow开发者调查中,近75%的开发者将其选为首选集成开发环境。VSCode提供了一系列开箱即用的特性和功能,但其真正的威力在于市场上庞大的扩展生态系统。整理了VSCode30大扩展列表,希望大家能使用这些......
  • 【愚公系列】2023年09月 WPF控件专题 Calendar控件详解
    (文章目录)前言WPF控件是WindowsPresentationFoundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见......
  • 2023/9/5 虹日刊 关键词:数字化零售
    ......
  • 2023年下半年软考开始报名!内附报名流程~
    重磅消息!2023年下半年软考报名,终于开始了!目前已经公布2023年下半年软考报名简章的省市有:广东,深圳,安徽,河北,云南,广西,江西,四川,吉林,辽宁,新疆、山东,甘肃,海南,内蒙古,黑龙江,西藏等地。  其中江西、辽宁、内蒙古、新疆地区2023年下半年软考报名今日开始,请各位考生仔细查看报名时间,尽快完成......
  • 2023年9月5日跟练
    1、打印1000到2000的闰年intmain(){ inti; intcount=0; for(i=1000;i<=2000;i++){ if((i%4==0&&i%100!=0)||(i%400==0)) { printf("%d",i); count++; } } printf("count=%d",count); return0;......
  • 2023.9 做题记录
    虽然第一天是8.31,但确实是开学第一个月,就一块算进去了。P2824法一:二分答案,将大于等于\(mid\)的数设为\(1\),小于的设为\(0\),最后位置上如果是\(1\)说明大于等于\(mid\),否则小于,时间复杂度\(O(n\logn)\),空间复杂度线性。法二(待做):线段树分裂,时间复杂度和空间复杂度均......
  • 接下来做的一些事20230905
    上一篇后缀自动机。数论。凸包。卷积。平衡树。圆方树。会尝试像\(6\)月的某段时间一样对自己做的每道题写一句话题解,以及评分。分数等级分为easy,easy+,medium,hard,hard+。每一档的意思为:easy自己能轻松做出来easy+自己花了一定功夫才能做出来medium会有些步骤......
  • 2023暑假集训总结-zxy
      在这个暑假集训期间,我度过了充实而有意义的日子,尽管没有很大的进步,也算是有些收获。 在集训中,我阅读完了老师曾经推荐的一本较为简单的数据结构的书,虽然我没有举一反三的能力,但也使我对数据结构有了初步的了解和认识。写题还是照样写不出来,但好像不像以往那样一头雾水了,是......
  • 2023暑假集训总结-lzg
    本人有幸成为程序设计基础暑期集训中的一员,在经历了长达两个月的集训后,我从中收获了很多。    首先是在集训中我学习到了很多知识,在这两个月里,我先是听了一部分ACwing上的课,学到了很多新的算法知识,不过现在掌握的还是相当不熟练。其次为了熟练运用新学到的知识我也在牛......