Stone的txl数

Stone的txl数

Time Limit: 1000MS  Memory Limit: 65536KB
Problem Description

Stone 将一个序列中 m 个区间的和命名为 txl 数(区间重叠部分只取一次)。

现在,Stone 从 QAQ 的桌子上获得了一个序列,他想知道这个序列的 txl 数是多少。

Input

输入数据有多组(数据组数不超过 50),到 EOF 结束。

每组数据第一行为两个数 n, m (1 <= n <= 10^5, 1 <= m <= 1000),分别代表序列的长度和区间的个数。

第二行为 n 个数代表该序列,(1 <= a[i] <= 10^7);接下来 m 行每行两个数 l, r (1 <= l <= r <= n),代表区间 [l, r]。

Output

对于每组数据,输出一行,表示该序列的 txl 数。

Example Input
10 3
1 2 3 4 5 6 7 8 9 10
1 3
2 4
3 5
Example Output
15
Hint
Author
Stone

注意long long
解法一:将区间排序,对区间进行更新累加

#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e6+10;
int n, m, l, r;
long long a[MAX], sum[MAX];
struct node
{
	int l, r;
}lxt[1100];
void Sort(int l, int r)
{
    for(int i = l; i<=r-1; ++i)
    {
        int k = i;
        for(int j = i+1; j<=r; ++j)
        {
            if(lxt[k].l>lxt[j].l)
                k = j;
        }
        if(k!=i)
            swap(lxt[i], lxt[k]);
    }
}
int main()
{
//freopen("data1.in", "r", stdin);
//freopen("data1.out", "w", stdout);
  while(~scanf("%d%d", &n, &m))
  {
  	sum[0] = 0;
  	for(int i = 1; i<=n; ++i)
	{
		scanf("%lld", &a[i]);
		sum[i] = sum[i-1]+a[i];
	}
	long long ans = 0;
	for(int i = 0; i<m; ++i)
		scanf("%d%d", &lxt[i].l, &lxt[i].r);
	Sort(0, m-1);
	int ll = lxt[0].l, rr = lxt[0].r;
	for(int i = 1; i<m; ++i)
	{
                if(lxt[i].l>rr)
		{
			ans+=sum[rr]-sum[ll-1];
			ll = lxt[i].l;
			rr = lxt[i].r;
		}
		else if(lxt[i].l>=ll&&lxt[i].r>=rr)
			rr = lxt[i].r;
	}
	ans+=sum[rr]-sum[ll-1];
	printf("%lld\n", ans);
  }
    return 0;
}




解法二:
b数组用来标记,左端点b[i]+1, 右端点b[i]-1
更新b[i] = b[1]+b[2]+....+b[i]
对于数组b[ ],任意b[i] >=0
b[i]>0 该点在区间内
搞不懂的可以在纸上写写示例的b[i]


#include <bits/stdc++.h>
using namespace std;
int a[100086],b[100086],n,m,i,l,r;
long long ans;
int main(){
    while(~scanf("%d %d",&n,&m)){
        ans=0;
        memset(b,0,sizeof(b));
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        while(m--){
            scanf("%d %d",&l,&r);
            b[l]++,b[r+1]--;
        }
        for(i=1;i<=n;i++){
            b[i]+=b[i-1];
            if(b[i])
                ans+=a[i];
        }
        printf("%lld\n",ans);
    }
    return 0;
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值