整体二分

来源:互联网 发布:毛阿敏 知乎 编辑:程序博客网 时间:2024/04/20 13:11
#include <stdio.h>#include <vector>#include <cstring>using namespace std;const int maxN=300010;struct Tnode{int l,r,c;}p[maxN];vector <int> e[maxN];long long tree[maxN];struct Tpoint{long long x;int y;}a[maxN],b[maxN];long long ans[maxN];int n,m,k;int add(int pos,int x){for (int i=pos; i<=m; i+=i&(-i))tree[i]+=(long long)x;}int query(int pos){long long ret=0;for (int i=pos; i>0; i-=i&(-i))ret+=tree[i];return ret;}void solve (int l,int r,int L,int R){if (l>r || L>R)return ;int mid=(l+r)/2;for (int i=l; i<=mid; i++){// printf("p[%d] l:%d r:%d c:%d\n",i,p[i].l,p[i].r,p[i].c);if (p[i].l<=p[i].r) add(p[i].l,p[i].c),add(p[i].r+1,-p[i].c);else add(1,p[i].c),add(p[i].r+1,-p[i].c),add(p[i].l,p[i].c);}int t1=L,t2=R;// printf( "%d ",mid);for (int i=L; i<=R; i++){int now=a[i].y;int len=e[now].size();long long sum=0;for (int j=0; j<len; j++)sum+=query(e[now][j]);if (sum>=a[i].x){ans[now]=mid;b[t1++]=a[i];}else{a[i].x-=sum;b[t2--]=a[i];} }for (int i=L; i<=R; i++)a[i]=b[i];for (int i=l; i<=mid; i++){if (p[i].l<=p[i].r) add(p[i].l,-p[i].c),add(p[i].r+1,p[i].c);else add(1,-p[i].c),add(p[i].r+1,p[i].c),add(p[i].l,-p[i].c);}if (t2!=R || r!=mid)solve(l,mid,L,t2);if (t1!=L || mid+1!=l)solve(mid+1,r,t1,R);}int main(){freopen("整体二分.in","r",stdin);freopen("整体二分.out","w",stdout);int T;scanf("%d",&T);while (T--){scanf("%d%d",&n,&m);memset(e,0,sizeof e);memset(tree,0,sizeof tree);memset(ans,0,sizeof ans);for (int i=1; i<=m; i++){int x;scanf("%d",&x);e[x].push_back(i);}for (int i=1; i<=n; i++){scanf("%d",&a[i].x);a[i].y=i; }scanf("%d",&k);for (int i=1; i<=k; i++)scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].c);solve(1,k,1,n);for (int i=1; i<=n; i++){if (ans[i]==0)printf("-1\n");else printf("%lld\n",ans[i]);} }return 0;}

原创粉丝点击