「BZOJ3932」[CQOI2015] 任务查询系统
好好的一道主席树题我写成了树状数组套主席树T T
原因是 为了练习模板
(一开始根本没想。。。)
T T
bzoj 16s通过,倒数第二是9s。。。多个log萌萌哒
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
#include<set> #include<map> #include<ctime> #include<queue> #include<cmath> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 100000000000000LL #define pa pair<int,int> #define ll long long using namespace std; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int m,n,cnt,mx; int q[100005],top; int S[100005],E[100005],P[100005],disc[100005]; int root[100005],size[20000005],a[20000005][2]; ll sum[20000005]; int insert(int x,int val,int f) { if(!x)x=++cnt; size[x]+=f;sum[x]+=f*disc[val]; int tmp=x; int l=1,r=2*m; while(l!=r) { int mid=(l+r)>>1,t=0; if(val>mid)t^=1,l=mid+1; else r=mid; if(!a[x][t])a[x][t]=++cnt; x=a[x][t];size[x]+=f; sum[x]+=f*disc[val]; } return tmp; } void update(int x,int val,int f) { for(int i=x;i<=n;i+=i&-i) root[i]=insert(root[i],val,f); } ll query(int x,int K) { ll ans=0,tot=0; top=0; for(int i=x;i;i-=i&-i) { q[++top]=root[i],tot+=size[root[i]]; ans+=sum[root[i]]; } if(K>tot)return ans; else ans=0; int l=1,r=2*m; while(l!=r) { int mid=(l+r)>>1,t,tmp=0; for(int i=1;i<=top;i++) tmp+=size[a[q[i]][0]]; if(tmp<K) { for(int i=1;i<=top;i++)ans+=sum[a[q[i]][0]]; t=1; K-=tmp,l=mid+1; } else r=mid,t=0; for(int i=1;i<=top;i++) q[i]=a[q[i]][t]; } ans+=1LL*K*disc[l]; return ans; } int main() { m=read();n=read(); for(int i=1;i<=m;i++) { S[i]=read(),E[i]=read(),P[i]=read(); disc[i]=P[i]; } sort(disc+1,disc+m+1); for(int i=1;i<=m;i++) { P[i]=lower_bound(disc+1,disc+m+1,P[i])-disc; update(S[i],P[i],1),update(E[i]+1,P[i],-1); } ll Pre=1,X,A,B,C,K; for(int i=1;i<=n;i++) { X=read();A=read();B=read();C=read(); K=1+(A*Pre+B)%C; Pre=query(X,K); printf("%lld\n",Pre); } return 0; } |
好像这个可以完全暴力
…
强制在线不幸福QAQ
所以你复杂度多少的,我nlog^2n 8s
nlog^2n。。。捂脸。。。
我也是阿= =我在主席树上二分的,感觉好逗,一个log的怎么做
我发现我更逗。。把初始操作优先级排序后搞到线段树里开vector存。
然后询问时取出所有线段树里的节点。
二分优先值再枚举每一个节点lower_bound。
竟然是log^3的。。。