整体二分,需要注意加的过程会爆long long,注意break掉
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<map> 4 #include<vector> 5 #include<cstring> 6 #define lb(x) (x&-x) 7 #define mp make_pair 8 #define pb push_back 9 #define fi first 10 #define sc second 11 #define N 600000 12 #define P 7777777 13 using namespace std; 14 typedef long long ll; 15 int n,m,a,b[N],p[N],tp[N],i,k,ans[N]; 16 vector<int> vec[N]; 17 ll c[N]; 18 struct g{ 19 int l,r,v; 20 }q[N]; 21 void cc(int x,int w) 22 { 23 while (x<=m+1) 24 { 25 c[x]+=w; 26 x+=lb(x); 27 } 28 } 29 ll sum(int x) 30 { 31 ll ans=0; 32 while (x) 33 { 34 ans+=c[x]; 35 x-=lb(x); 36 } 37 return ans; 38 } 39 void solve(int ql,int qr,int l,int r) 40 { 41 int i,j,tl,tr,mid; 42 if (ql>qr) return; 43 mid=(l+r)>>1; 44 for (i=l;i<=mid;i++) 45 { 46 if (q[i].l<=q[i].r) 47 { 48 cc(q[i].l,q[i].v); 49 cc(q[i].r+1,-q[i].v); 50 } 51 else 52 { 53 cc(1,q[i].v); 54 cc(q[i].r+1,-q[i].v); 55 cc(q[i].l,q[i].v); 56 cc(m+1,-q[i].v); 57 } 58 } 59 60 if (l==r) 61 { 62 for (i=ql;i<=qr;i++) 63 { 64 ll cnt=0; 65 for (j=0;j<vec[p[i]].size();j++) 66 { 67 cnt+=sum(vec[p[i]][j]); 68 if (cnt>=b[p[i]]) break; 69 } 70 if (cnt>=b[p[i]]) ans[p[i]]=l;else ans[p[i]]=-1; 71 } 72 } 73 else 74 { 75 tr=qr+1; 76 tl=ql-1; 77 for (i=ql;i<=qr;i++) 78 { 79 ll cnt=0; 80 for (j=0;j<vec[p[i]].size();j++) 81 { 82 cnt+=sum(vec[p[i]][j]); 83 if (cnt>=b[p[i]]) break; 84 } 85 if (cnt<b[p[i]]) 86 { 87 b[p[i]]-=cnt; 88 tp[--tr]=p[i]; 89 } 90 else 91 tp[++tl]=p[i]; 92 } 93 for (i=ql;i<=qr;i++) p[i]=tp[i]; 94 } 95 for (i=l;i<=mid;i++) 96 { 97 if (q[i].l<=q[i].r) 98 { 99 cc(q[i].l,-q[i].v); 100 cc(q[i].r+1,q[i].v); 101 } 102 else 103 { 104 cc(1,-q[i].v); 105 cc(q[i].r+1,q[i].v); 106 cc(q[i].l,-q[i].v); 107 cc(m+1,q[i].v); 108 } 109 } 110 if (l==r) return; 111 solve(ql,tl,l,mid); 112 solve(tr,qr,mid+1,r); 113 } 114 int main() 115 { 116 scanf("%d%d",&n,&m); 117 for (i=1;i<=m;i++) 118 { 119 scanf("%d",&a); 120 vec[a].pb(i); 121 } 122 for (i=1;i<=n;i++) scanf("%d",&b[i]); 123 scanf("%d",&k); 124 for (i=1;i<=n;i++) 125 p[i]=i; 126 for (i=1;i<=k;i++) 127 scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].v); 128 solve(1,n,1,k); 129 for (i=1;i<=n;i++) 130 if (ans[i]==-1) 131 printf("NIE "); 132 else 133 printf("%d ",ans[i]); 134 }