7.14做题总结

今天啥也没学,我也算是废了,随便从我写的题里面抽两道总结一下吧

P2671 [NOIP2015 普及组] 求和

这题我们的暴力解决方法,为枚举x和z然后通过x+z/2=y.来得到y,但是我们发现这中做法的时间复杂度为O(n^2),很明显对于我们这题来说时间复杂度是一定超了的,那么我们再想,会不会有一些可以简单复杂度的方法,那么我们只能用到我们的分治思想了,因为要求的是x,z的颜色是要一样的,那么我们就让他一样,给每个颜色进行分组,分成m组,然后再对里面的编号进行分奇偶处理,因为x与z是同奇同偶的,因此,总共会分成m组,那么我们来推一下公式是什么

如果一个里面有三个元素,标号为x1,x2,x3,值为y1,y2,y3

那么计算公式为:

(x1+x2)*(y1+y2)+(x1+x3)*(y1+y3)+(x2+x3)+(y2+y3)

x1*(y1+y2+y1+y3)+x2*(y2+y1+y2+y3)+x3*(y3+y1+y3+y2)

所以可以总结一下公式,也就是标号*((cnt-1)(这个标号颜色有多少个)+这个标号的颜色的前缀和)

因此代码为

#include<bits/stdc++.h>
using namespace std;
#define int long long

int n,m;
int num[100005];
int color[100005];
int cnt[100005][2];//统计每种颜色奇偶性的个数
int pre[100005][2];//值的前缀和数组
int mod=10007;
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	cin>>num[i];
	for(int i=1;i<=n;i++)
	{
		cin>>color[i];
		cnt[color[i]][i%2]++;
		pre[color[i]][i%2]=(pre[color[i]][i%2]+num[i])%mod;
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		ans=(ans+(i*(cnt[color[i]][i%2]-2)*num[i])%mod+(i*pre[color[i]][i%2])%mod)%mod;
	}
	cout<<ans;
	return 0;
 } 

 P2880 [USACO07JAN] Balanced Lineup G

区间询问,咱们的老朋友了,直接写代码就行

#include<bits/stdc++.h>
using namespace std;
#define int long long

int n,m;
int h[50005];
struct node{
    int l;
    int r;
    int sum;
    int maxn;
    int minn;
}tree[50005*4];

void build(int i,int l,int r)
{
    tree[i].l=l,tree[i].r=r;
    if(l==r)
    {
        tree[i].maxn=h[l];
        tree[i].minn=h[l];
        return ;
    }
    int mid=(l+r)/2;
    build(i*2,l,mid);
    build(i*2+1,mid+1,r);
    tree[i].maxn=max(tree[i*2].maxn,tree[i*2+1].maxn);
    tree[i].minn=min(tree[i*2].minn,tree[i*2+1].minn);
}

int find_max(int i,int l,int r)
{
    if(tree[i].l>=l&&tree[i].r<=r)
    {
        return tree[i].maxn;
    }
    int mid=(tree[i].l+tree[i].r)/2;
    int maxn=-1;
    if(mid>=l)
    {
        maxn=max(maxn,find_max(i*2,l,r));
    }
    if(mid+1<=r)
    {
        maxn=max(find_max(i*2+1,l,r),maxn);
    }
    return maxn;
}

int find_min(int i,int l,int r)
{
    if(tree[i].l>=l&&tree[i].r<=r)
    {
        return tree[i].minn;
    }
    int mid=(tree[i].l+tree[i].r)/2;
    int minn=0x3f3f3f3f;
    if(mid>=l)
    {
        minn=min(minn,find_min(i*2,l,r));
    }
    if(mid+1<=r)
    {
        minn=min(find_min(i*2+1,l,r),minn);
    }
    return minn;
}

signed main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>h[i];
    }
    build(1,1,n);
    int x,y;
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;
        cout<<find_max(1,x,y)-find_min(1,x,y)<<"\n";
    }
    return 0;
}

 

相关推荐

  1. C++_第四周总结

    2024-07-16 09:54:03       34 阅读
  2. 3月13日总结(Linux真

    2024-07-16 09:54:03       40 阅读
  3. C++_第三周总结_指针2

    2024-07-16 09:54:03       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 09:54:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 09:54:03       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 09:54:03       58 阅读
  4. Python语言-面向对象

    2024-07-16 09:54:03       69 阅读

热门阅读

  1. Ajax是什么?如何在HTML5中使用Ajax?

    2024-07-16 09:54:03       24 阅读
  2. C 语言 do while 语句

    2024-07-16 09:54:03       25 阅读
  3. Apache Spark 的基本概念和在大数据分析中的应用

    2024-07-16 09:54:03       21 阅读
  4. Linux上启动和停止jar

    2024-07-16 09:54:03       25 阅读
  5. MVCC到底是什么,怎么优化

    2024-07-16 09:54:03       27 阅读
  6. hnust 2179:创建二叉树并计算深度

    2024-07-16 09:54:03       21 阅读