维护一个长度为n的序列,一开始都是0,支持以下两种操作:
1.U k a 将序列中第k个数修改为a。
2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作。
每次询问独立,即每次询问不会对序列进行修改。
维护一个长度为n的序列,一开始都是0,支持以下两种操作:
1.U k a 将序列中第k个数修改为a。
2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作。
每次询问独立,即每次询问不会对序列进行修改。
第一行包含两个正整数n,m(1<=n,m<=1000000),分别表示序列长度和操作次数。
接下来m行为m个操作,其中1<=k,c<=n,0<=a<=10^9,1<=s<=10^9。
包含若干行,对于每个Z询问,若可行,输出TAK,否则输出NIE。
#include<set> #include<map> #include<queue> #include<cmath> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; int cnt; char s[20]; int a[1000010]; int b[1000010]; int c[1000010]; int d[1000010]; int e[1000010]; int h[1000010]; struct node { long long v[1000010]; void add(int x,int t) { for(;x<=cnt;x+=x&-x) { v[x]+=t; } } long long query(int x) { long long res=0; for(;x;x-=x&-x) { res+=v[x]; } return res; } }b1,b2; int find(int x) { int l=1,r=cnt,mid; while(l<r) { mid=(l+r)>>1; if(h[mid]<x) { l=mid+1; } else { r=mid; } } return l; } int main() { int num; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%s",s); scanf("%d%d",&b[i],&c[i]); e[i]=c[i]; if(s[0]==‘U‘) { d[i]=1; } } sort(e+1,e+m+1); h[++cnt]=e[1]; for(int i=2;i<=m;i++) { if(e[i]!=e[i-1]) { h[++cnt]=e[i]; } } for(int i=1;i<=m;i++) { c[i]=find(c[i]); } for(int i=1;i<=m;i++) { if(d[i]) { if(num=a[b[i]]) { b1.add(num,-1); b2.add(num,-h[num]); } a[b[i]]=c[i]; b1.add(c[i],1); b2.add(c[i],h[c[i]]); } else { b2.query(c[i]-1)>=(b[i]-b1.query(cnt)+b1.query(c[i]-1))*h[c[i]]?printf("TAK\n"):printf("NIE\n"); } } }
BZOJ4378[POI2015]Logistyka——树状数组
原文:https://www.cnblogs.com/Khada-Jhin/p/9593643.html