题目大意:给n个数,给定多次区间修改操作,操作是给区间数+1,修改完后询问+k的数的原来权值和
思路:差分、离散化
这题时限给的很紧张(感觉读入就会tle???O(n方),甚至开了快读,数组初始化不用memset,才勉强过
大致讲一下思路,首先所有区间离线处理,排序,利用差分数组dlt[N],左端点dlt[l]++,右端点dlt[r+1]--(需要往右边多走一步,记录区间修改+1操作,只需要记录左右端点即可)
然后处理区间当 修改次数==k时,算一下权值和,权值和我们一开始就用前缀和处理一下,数组记为sum[N],设此时处理当第i个端点,和前一个端点i-1构成 "修改次数==k"这个结果,权值和ans += sum[i-1] - sum[i-1-1];
因为时限原因,普通的结构体存端点离散化需要sort,并且因为结构体长度是2*n,种种因素,我们利用map去存端点,情况数组也只要通过map去情况差分数组dlt,但凡想少了一点优化就会tle,最后注意k==0 时需要特判,因为k!=0时,我们算的都是被覆盖的区间,k==0时,区间最后一段,也就是最后一个右端点到n这个区间,按照原来方法是不会被算到的。注意开longlong
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define all(v) v.begin() , v.end()
#define pb(v) push_back(v)
#define INF 0x3f3f3f3f
#define int long long
#define lson p*2,l,mid
#define rson p*2+1,mid+1,r
typedef long long ll;
const int N =1e6+10;
const int mod = 1e9+7;
int b[N];
int sum[N];//前缀和
int n,m,day;
map<int , int > mp;
inline int read() {
int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}
signed main()
{
//!!!!!!!!!!!!!!!!!!!!!!
// freopen("data.txt","r",stdin);
//!!!!!!!!!!!!!!!!!!!!!!
int T;
T=read();
while( T-- )
{
cin>>n>>day;
_for(i,1,n)
{
int x;
x=read();
sum[i] = x + sum[i-1];
}
_for(i,1,day)
{
int q,t;
q=read(),t=read();
_for(j,1,q)
{
int l,r;
l=read(),r=read();
//读入时离散化,存端点即可
b[l]++;
b[r+1]--;
mp[l]=1;
mp[r+1]=1;
}
map <int , int > ::iterator it;
int temp =0 ;
int pre=1;
ll ans =0;
//特判
if( t==0 )
{
for(it=mp.begin() ; it!=mp.end(); it++)
{
if( temp ==0 ) ans += sum[it->first-1] - sum[pre-1];//当修改次数达到目标时,算权值
temp += b[it->first];
pre = it->first;//记录上一个端点的位置
}
ans += sum[n] - sum[pre-1];//算最后一个区间
}
else
{
//和上面同理
for(it=mp.begin() ; it!=mp.end(); it++)
{
if( temp == t) ans += sum[it->first-1] - sum[pre-1];
temp += b[it->first];
pre = it->first;
}
}
printf("%lld\n",ans);
for(it=mp.begin() ; it!=mp.end(); it++) b[it->first] =0;
// mst(b,0);
mp.clear();
}
_for(i,1,n) sum[i]=0;
}
}