BZOJ_4378_[POI2015]Logistyka_tree array
Description
Maintain a sequence of length n, which is 0 at the beginning, and supports the following two operations:
1.U ka Modify the kth number in the sequence to a.
2.Z cs On this sequence, select c positive numbers each time, subtract 1 from them, and ask if you can perform s operations.
Each query is independent, i.e. the sequence is not modified per query.
Input
The first line contains two positive integers n, m (1<=n, m<=1000000), which represent the sequence length and the number of operations, respectively.
The next m lines are m operations, where 1<=k, c<=n, 0<=a<=10^9, 1<=s<=10^9.
Output
Contains several lines, for each Z query, output TAK if feasible, NIE otherwise.
Sample Input
3 8
U 1 5
U 2 7
Z 2 6
U 3 1
Z 2 6
U 2 2
Z 2 6
Z 2 1
U 1 5
U 2 7
Z 2 6
U 3 1
Z 2 6
U 2 2
Z 2 6
Z 2 1
Sample Output
NO
YES
NO
YES
YES
NO
YES
Note that the query is on the entire sequence and not on a given interval.
Assuming that there are k numbers greater than s, the sum of the remaining weights must be greater than or equal to (ck)*s.
So we discretize the weights and maintain them separately in two tree-like arrays.
Code:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 1000050 #define RR register typedef long long ll; int n,m,t[N],maxn=1000000000,h[N],p[N]; ll c[N][2]; char opt[10]; inline int rd() { RR int x=0,f=1; RR char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();} return x*f; } struct A { int num,v,id,opt,pos; }a[N]; inline bool cmp1(const A &x,const A &y){return x.num<y.num;} inline bool cmp2(const A &x,const A &y){return x.id<y.id;} void fix(int x,int v,int flg) { for(;x<=m;x+=x&(-x)) c[x][flg]+=v; } ll inq (int x, int flg) { ll re=0; for(;x;x-=x&(-x)) re+=c[x][flg]; return re; } int main() { n=rd(); m=rd(); int i,j; for(i=1;i<=m;i++) { scanf("%s",opt); if(opt[0]=='U') { a[i].opt=1; a[i].id=i; a[i].pos=rd(); a[i].num=rd(); }else { a[i].opt=2; a[i].id=i; a[i].pos=rd(); a[i].num=rd(); } } sort(a+1,a+m+1,cmp1); a[0].num=134234; for(j=0,i=1;i<=m;i++) { if(a[i].num!=a[i-1].num) j++; a[i].v=j; h[j]=a[i].num; } sort(a+1,a+m+1,cmp2); for(i=1;i<=m;i++) { if(a[i].opt==1) { int t=a[i].pos; if(p[t]) { fix(p[t],-1,1); fix(p[t],-h[p[t]],2); } p[t]=a[i].v; fix(p[t],1,1); fix(p[t],h[p[t]],2); }else { int k=inq(m,1)-inq(a[i].v-1,1); if(k>=a[i].pos) { puts("TAK"); continue; } ll sum=inq(a[i].v-1,2); puts(sum>=1ll*a[i].num*(a[i].pos-k)?"TAK":"NIE"); } } }