18100 奇怪的光照植物
该题有题解
时间限制:500MS 代码长度限制:10KB
提交次数:547 通过次数:64
题型: 编程题 语言: G++;GCC;VC
Description
一种光照植物,用光照射一天就长1厘米。现在将这种植物种在一条直线型的
培养容器中,坐标从0到n-1,每一个整点位置种植一棵这种植物,即共n棵。
开始的时候所有植物的高度都为0。实验过程中,进行了m组,每组选择对范围为
[L,R]的植物进行光照a天,每组参数L、R、a由输入数据给出。
当所有实验结束后,我们想知道所有光照了奇数天的植物总的高度是多少(单位:厘米)。
输入格式
输入第一行包含一个整数T(T<=10),表示有T组测试数据。
对每一组测试数据,第一行是两个数n(1<=n<=106)和m(0<=m<=105),用空格分隔。
接下来的m行中每一行包含三个数L,R和a(0<=L<=R<=n-1,0<=a<=100),用空格分隔,表示一个操作。
输出格式
对于每组测试数据输出一行,所有实验操作后所有光照了奇数天的植物总的高度
输入样例
1
10 3
3 5 1
4 9 1
8 9 0
输出样例
5
题意:给出一个序列,每次询问对区间【L,R】+a,问最后加了奇数次的元素和 |
(差分):
1.首先,肯定要找个O(n)的方法或者O(nlogn)的方法,暴力肯定不行。
2.因为是对区间操作,所以考虑差分。什么是差分?若原序列a1…a2…a3…an,差分序列即是d1 = a[1] - a[0] , d2 = a[2] - a[1] , d[3] = a[3] - a[2]… d[n] = a[n] - a[n-1]。
3.差分有什么性质?你会发现差分的前i项和就是对应a[i]。 差分有什么用?这样我们在对每次询问的时候,比如【3,5】的区间+1,就可以看出是 d[3]++, d[5+1] --。怎么理解?就看成是第三个元素比前面多了1,第6个元素比前面小了1 , 这样的效果不就是【3,5】区间多了1吗?对于每个询问也是如此。
4.所以每次询问只需要简单的对d数组操作一下。然后询问完了我们拿到一个处理完的d数组,求回原数组a不是手到擒来的事情吗?(前面说了,求个前缀和就是a)。
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e6+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'|ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll d[maxn];
ll a[maxn];
int main()
{
int kase;
cin>>kase;
while(kase--)
{
mem(d,0);
ll n = read(), m = read();
rep(i,1,m)
{
ll l = read(), r = read(), x = read();
l++, r++;
d[l] += x, d[r+1] -= x;
}
ll sum = 0;
rep(i,1,n) a[i] = d[i] + a[i-1];
rep(i,1,n) if(a[i]&1) sum += a[i];
cout<<sum<<'\n';
}
return 0;
}