第一次学习整体二分,我感觉这个复杂度玄学啊
莫队算法在变权的时候是不是和这个的Tim异曲同工?
明显答案相对独立
明显时间可以二分
经典整体二分
但是小心哲学数据点8metb
炸Long Long
#include<bits/stdc++.h>
using namespace std;
typedef int INT;
#define int long long
const int INF=1e17+7;
const int N=3e5+500;
inline void read(int &x){
x=0;
char ch=getchar();
int f=1;
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
int n,m;
vector<int>T[N];// 以国家的视角看下标
int Loc[N]={};// 当前下标对应国家
int Goal[N]={};//当前国家目标 陨石量
int Belong[N]={};//该空间站属于什么国家
int St[N]={};
int Ed[N]={};
int Val[N]={};
int ans[N]={};
int Get[N]={};//在二分时间点的陨石数
int k;
int tim=0;
int Lc[N]={};
int Rc[N]={};
//----------
int Tree[N]={};
const int maxn=300010;
inline int Lowbit(int x){
return x&(-x);
}
inline void update(int x,int val){
while(x<=m){
Tree[x]+=val;
x+=Lowbit(x);
}
}
inline int Query(int x){
int ret=0;
while(x){
ret+=Tree[x];
x-=Lowbit(x);
}
return ret;
}
inline void Change(int St,int Ed,int Val){
// cout<<St<<" "<<Ed<<" "<<Val<<'\n';
if(St<=Ed){
update(St,Val);
update(Ed+1,-Val);
}
else{
update(St,Val);
update(m+1,-Val);
update(1,Val);
update(Ed+1,-Val);
// Change(1,Ed,Val);
// Change(St,m,Val);
}
}
void Solve(int l,int r,int L,int R){
// cout<<l<<" "<<r<<" "<<L<<" "<<R<<'\n';
if(l>r)return;
if(L>R)return;
if(l==r){
for(int i=L;i<=R;i++)
ans[Loc[i]]=l;
return;
}
int mid=(l+r)/2;
while(tim<mid)tim++,Change(St[tim],Ed[tim],Val[tim]);
while(tim>mid)Change(St[tim],Ed[tim],-Val[tim]),tim--;
// cout<<"here"<<'\n';
for(int i=L;i<=R;i++){
Get[Loc[i]]=0;
for(int j=0;j<T[Loc[i]].size();j++){
Get[Loc[i]]+=Query(T[Loc[i]][j]);
if(Get[Loc[i]]>Goal[Loc[i]])break;
}
}
// cout<<mid<<" "<<Get[1]<<'\n';
// cout<<"here"<<'\n';
int left_cnt=0;
int right_cnt=0;
for(int i=L;i<=R;i++){
if(Get[Loc[i]]>=Goal[Loc[i]])Lc[++left_cnt]=Loc[i];
else Rc[++right_cnt]=Loc[i];
}
for(int i=1;i<=left_cnt;i++)Loc[i+L-1]=Lc[i];
for(int i=1;i<=right_cnt;i++)Loc[i+left_cnt+L-1]=Rc[i];
int Half=left_cnt;
Solve(l,mid,L,L+Half-1);
Solve(mid+1,r,L+Half,R);
}
INT main(){
// freopen("met8b.in","r",stdin);
// freopen("P3527.out","w",stdout);
read(n);
read(m);
for(int i=1;i<=m;i++){
read(Belong[i]);
T[Belong[i]].push_back(i);
}
for(int i=1;i<=n;i++)read(Goal[i]),Loc[i]=i;
read(k);
for(int i=1;i<=k;i++){
read(St[i]);
read(Ed[i]);
read(Val[i]);
}
k++;
St[k]=1;
Ed[k]=m;
Val[k]=INF;
Solve(1,k,1,n);
for(int i=1;i<=n;i++){
if(ans[i]==k)puts("NIE");
else cout<<ans[i]<<'\n';
}
return 0;
}